2012-11-05 23 views
1

我們有一個Ruby on Rails應用程序。如何調用Ruby和Gem AASM轉換事件的狀態?

我們使用Ruby的aasm gem來管理對象的狀態。

<pre> 
has_state 
aasm do 
    state :created, :initial => true 
    state :submitted 
    state :rejected 
    state :approved 

    event :submit do 
     transitions :to => :submitted, :from => [:created] 
    end 

    event :mark_as_incomplete do 
     transitions :to => :created, :from => [:submitted] 
    end 

    event :approve do 
     transitions :to => :approved, :from => [:submitted] 
    end 

    event :reject do 
     transitions :to => :rejected, :from => [:submitted] 
    end 
end 
<code> 

如果我們知道一個對象的當前狀態,可以使用

<pre> 
object.aasm_current_state 
<code> 

獲得,我們也知道過渡到狀態,如何才能調用事件?

請注意,from-state和to-state是變量,所以我們需要動態地執行上述 。當然,對於某些狀態和狀態組合,轉換不可用,在這種情況下,我們應該檢測到錯誤。

我們還在之間任何兩個狀態組合(以狀態和狀態),這裏只有1個事件,我覺得理論上可以有假設大於1

我認爲這是可以通過以下方式實現深入研究aasm源代碼的內部, ,可以說,這可能不是一個好的做法。有什麼想法嗎?

只是想知道如果有人以前做過這個。

謝謝!

回答

1

AASM沒有辦法做到這一點,但你自己的答案已經足夠接近你想去的地方。 AASM是圍繞這個假設而建立的,即狀態機允許從一個狀態到另一個狀態的多種不同的轉換。

如果事件名稱是不相關的,你可以重複使用,以國家名稱爲事件名稱,像這樣:

aasm do 
    ... 
    event :approved do 
    transitions :from => :submitted, :to => :approved 
    end 
    ... 
end 

通過這一點,你可以通過只知道到狀態觸發事件命名

approval_request.send(to_state) 

默認情況下,AASM拋出一個異常如果不允許這種轉變。如果你不喜歡例外,設置whiny_transitionsfalse,像這樣:

aasm :whiny_transitions => false do 
    ... 
end 
+0

謝謝。是的,這會起作用。儘管稍後有人更改事件名稱,但它將停止工作。我的代碼更通用,因爲它不依賴於事件名稱。雖然我的代碼在第一次轉換時會在任何兩個狀態之間找到並執行它。如你所說,可能還有其他的轉變。 –

0

這是我的代碼。 to_state和from_state是來自和去往的狀態。

ApprovalRequest.aasm_events.each do |event_key, event_obj| 
    if event_obj.transitions_from_state?(from_state) && 
     event_obj.transitions_to_state?(to_state) 
     self.approval_request.send "#{event_key.to_s}!" 
    end 
end 

對此實施的任何評論?

+0

你需要得到AASM寶石的這個分支(直到我改變合併到主GIT):https://開頭github上。 com/zackxu1/aasm –

+0

現在我知道了,你需要'transitions_to_state?'作爲。 ;-) – alto