views:

107

answers:

2

Hi all,

I have a model that relies on state_machine to manage its different states. One particular event requires a before_transition as it needs to build a join table fore doing the transition. Unfortunately it doesn't work.

class DocumentSet < ActiveRecord::Base

  state_machine :state, :initial => :draft do
    # Callbacks
    before_transition :on=>:submit, :do=>:populate_join_table

    # States
    state :draft
    state :submitted

    # Events
    event :submit do transition :draft=>:submitted, :if=>:can_submit? end
  end

def populate_join_table
   puts '::::::::: INSIDE POPULATE_JOIN_TABLE'
end

def can_submit?    
  raise "Document Set has no Document(s)" if self.document_versions.blank?
  true
end

Now when I do DocumentSet.submit, it actually never goes into the populate_join_table as it evaluates the can_submit? as false.

What am I missing?

Thx!

A: 

Think I found the solution. Basically what happens is that state_machine first evaluates the :if condition, and only then does the before_transition.

So the order is:

If (GuardCondition == true)
  run before_transition
  run transition
  run before_transition

Can anybody confirm?

Thx.

khelal
A: 

The guard condition(s) controls whether or not that event (and transition) is valid at that time. In this case, your guard returns false, so you won't transition. This can be extremely useful, but in your case, you might need to rework/rethink things to let that callback run.

dunedain289