In my current side-project I'm playing with using acts_as_state_machine to implement some of my model behaviour.
Now, it has occurred to me that using this pattern is in some way in conflict with the way that things are normally done in rails.
For example, I find my guard functions (for the state transitions) are duplicating validations on my model.
A specific example of this is a User model. It validates_presence_of, validates_confirmation_of and validates_length :password. Additionally, the transition from verified to active has a guard function which makes sure that the password is valid.
This duplication seems necessary in part because the state transitions use update_attribute to change state (thereby bypassing validations)... so, the guard function has to worry about things. Unfortunately, this also means that firing an event/transition can commit a model in an invalid state. I can add valid? to the guard, but then all the guard function can do is prevent the transition... not report any errors...
At this point I start to think that there's a general flaw in either the implementation, or in my usage of the plugin.
It also seems to me that I should be able to set the state manually in an model while I'm changing other attributes. Then, when I save, a series of callbacks could detect the implied transition and guard if necessary (inline with the other validations?), plus implement with the various enter and exit state callbacks.
So, what I'm wondering here on core is... is there a more rails-like way to do these sorts of things? It seems that using observers to "notice" state changes is the more rails-like way... but then you don't get the extra event transition methods, state testing methods, etc.
Is this something that a new, more rails-like "state_machine_fu" plugin should implement... with the possibility of merging into core later? Does anyone have any suggestions for what the "more rails-like" way would be? General thoughts?
Cheers.