4

我试图让人们可以在类中定义任意工作流。这个代码对于 Stack Overflow 来说可能太长了,所以我有一个要点

如果您运行代码,前几个测试将起作用,但是当它尝试转换到支付状态时,它会检查payment_required?完全错误对象上的方法。我希望它在当前Order实例上检查它,但它(似乎)正在状态机匿名类上寻找该方法。

如何让它在Order实例上正确调用该方法?

4

2 回答 2

0

我已经通过将状态机定义移动到Spree::Order类来解决这个问题。您可以在此拉取请求中看到工作。

于 2012-07-12T07:18:04.367 回答
0

问题出在匿名状态机的定义上,大约在第 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
于 2012-07-06T03:50:45.943 回答