2012-07-05 37 views
4

我正在試圖讓人們可以在類中定義任意的工作流程。這個代碼對Stack Overflow來說可能太長了,所以我得到了a gist定義一個自定義狀態機

如果您運行代碼,則第一對測試將起作用,但當它嘗試轉換到付款狀態時,它會檢查完全錯誤對象上的payment_required?方法。我希望它在當前的Order實例上檢查它,但是它(看起來)正在狀態機匿名類中尋找這種方法。

如何讓它在Order實例上正確調用方法?

+0

這是142行上的拼寫錯誤嗎?看起來應該是殘留謂詞方法「payment_required?」而不僅僅是「payment_required」。 –

+0

我真的不明白''payment_required'是在哪裏定義的。你已經寫了'go_to:payment,:if =>:order'not'go_to:payment,:if =>:payment_required'。你能進一步解釋嗎? – Gerry

回答

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 
0

我由狀態機定義移動到Spree::Order類固定這件事。您可以在this pull request中查看該作品。