我试图让人们可以在类中定义任意工作流。这个代码对于 Stack Overflow 来说可能太长了,所以我有一个要点。
如果您运行代码,前几个测试将起作用,但是当它尝试转换到支付状态时,它会检查payment_required?
完全错误对象上的方法。我希望它在当前Order
实例上检查它,但它(似乎)正在状态机匿名类上寻找该方法。
如何让它在Order
实例上正确调用该方法?
我试图让人们可以在类中定义任意工作流。这个代码对于 Stack Overflow 来说可能太长了,所以我有一个要点。
如果您运行代码,前几个测试将起作用,但是当它尝试转换到支付状态时,它会检查payment_required?
完全错误对象上的方法。我希望它在当前Order
实例上检查它,但它(似乎)正在状态机匿名类上寻找该方法。
如何让它在Order
实例上正确调用该方法?
我已经通过将状态机定义移动到Spree::Order
类来解决这个问题。您可以在此拉取请求中看到工作。
问题出在匿名状态机的定义上,大约在第 42 行:
order.class.transitions.each { |attrs| transition(attrs) }
这意味着转换保护是在匿名状态机的上下文中评估的,而不是在Order
类的上下文中。
一种解决方案是翻译过渡守卫。用此替换上面的行以通过您的测试套件:
order.class.transitions.each do |attrs|
if attrs[:if].is_a? Symbol
if_method = attrs[:if]
attrs[:if] = lambda { order.send( if_method ) }
end
transition(attrs)
end
您将需要支持所有类型的转换保护以获得完整的解决方案。建议看StateMachine::EvalHelpers
全套。
更正:
正如其他人所提到的,您还需要修复您的测试套件:
go_to :payment, :if => :payment_required? # Line 107
order.stub :payment_required? => true # Line 142