Nov 20 2010
∞
Fun state_machine rspec gotcha
Let’s say you’ve got the following:
class Thing :draft do
event :publish do
transition all => :published
end
state :published do
validates_presence_of :author
end
end
end
You want to test your validations on the state transition like so:
it "requires an author to transition to published" do
thing = Thing.new
thing.author.should be_nil
thing.publish
thing.should have(1).error_on(:author)
end
This test fails.
Why?
1) When a state_machine transition fails, it automatically rolls you back to the prior state.
2) The prior state will now be valid, as we don’t have the extra validations added by state machine. Calling valid? at this point will clear out the (correct) errors that state_machine added to your object when it tried to transition it.
3) error_on calls valid? under the hood.
This seems to have implications for controllers too — you’d never want to change a state and then save, you’d always want to thing.save if (thing.publish).
An interesting gotcha that confounded me for a bit, particularly since the internals of state_machine tend towards the meta. Eventually I just poked at my model in a console until I figured out what was going on.