acts_as_state_machine override :initial state


I'm not sure if this is where to post this, but i cannot find much
information/support for acts_as_state_machine.

I have a Friendship model which implements acts_as_state_machine. I
have an :initial state of :pending, but i would like to create a
Friendship model and save it directly with :accepted status.

I have tried Friendship.create(:state => "accepted") and,
friendship.state = "accepted", .save!...but neither have worked. The
only way i can accomplish this is by doing:
friendship = Friendship.create
friendship.state = "accepted"!

However, i do not like this since it has an unnecessary DB hit. Anybody
know how i can do this?


You could modify set_initial_state in acts_as_state_machine.rb as

        def set_initial_state #:nodoc:
          write_attribute self.class.state_column,
self.class.initial_state.to_s if self.state.nil?

That way if you specify an initial state it won't assign the default
initial state in before_create. You'd probably also need to modify
run_initial_state_actions (which is run by the after_create callback)
along the lines of:

        def run_initial_state_actions
          if self.state.to_sym === self.class.initial_state.to_sym
            initial = self.class.read_inheritable_attribute(:states)

So that the actions for the default initial state don't run.

This does rather defeat the purpose of using acts_as_state_machine
though. :slight_smile:

The thing is, then you've no longer got a state machine. It's like
having a goto in code. Could the :initial state route it to :accepted?
As far as the db access goes, that's generally the last thing you
should worry about, in my opinion.