Closed benzelano closed 13 years ago
I’m absolutely all for shipping more examples in the library. There are only a few in there right now and they’re pretty basic. However, I don’t personally have any state machines that I would pitch as standard... perhaps "starter" kits (which I’m dubbing "examples" in this case). I definitely encourage submitting a patch for adding to the examples directory.
Closing as resolved. Feel free to re-open the ticket if you create other examples or simply send a pull request on github. Thanks!
Aaron Gibralter opened this issue
Have you ever thought of creating a standardized collection of state_machines that represents best practices for user-group membership related states?
I have a pretty complicated set of state_machines that represents a user being invited to a group (based roughly on, say, facebook’s group invite system):
@@@ state_machine :state_user, :initial => :pending, :namespace => :by_user do
before_transition :to => :accepted do |membership| membership.activate(false) true end
before_transition :to => :suspended do |membership| membership.deactivate(false) true end
before_transition :from => :suspended do |membership| membership.activate(false) true end
event :request do transition :to => :requested, :from => :pending, :if => lambda { |membership| membership.by_admin_pending? } transition :to => :accepted, :from => [:pending, :rejected, :suspended], :if => lambda { |membership| membership.by_admin_requested? } transition :to => :requested, :from => :suspended, :if => lambda { |membership| membership.by_admin_accepted? } end
event :cancel do transition :to => :pending, :from => :requested, :if => lambda { |membership| membership.by_admin_pending? } end
event :reject do transition :to => :rejected, :from => :pending, :if => lambda { |membership| membership.by_admin_requested? } end
Can suspend if you are active
Last admin cannot suspend his or herself
event :suspend do transition :to => :suspended, :from => [:accepted, :requested], :if => lambda { |membership| !membership.admin? || membership.group.admins.size > 1 } end end
state_machine :state_admin, :initial => :pending, :namespace => :by_admin do
before_transition :to => :accepted do |membership| membership.activate(false) true end
before_transition :to => :suspended do |membership| membership.deactivate(false) true end
before_transition :from => :suspended do |membership| membership.activate(false) true end
event :pre_accept do transition :to => :accepted, :from => :pending end
event :request do transition :to => :requested, :from => :pending, :if => lambda { |membership| membership.by_user_pending? } transition :to => :accepted, :from => [:pending, :rejected, :suspended], :if => lambda { |membership| membership.by_user_requested? } transition :to => :requested, :from => :suspended, :if => lambda { |membership| membership.by_user_accepted? } end
event :cancel do transition :to => :pending, :from => :requested, :if => lambda { |membership| membership.by_user_pending? } end
event :reject do transition :to => :rejected, :from => :pending, :if => lambda { |membership| membership.by_user_requested? } end
Cannot suspend other admins
event :suspend do transition :to => :suspended, :from => [:accepted, :requested], :if => lambda { |membership| !membership.admin? } end end @@@
This leads to the following full/combined states: @@@
full states:
- nothing
- member
- requested_by_user
- requested_by_admin
- rejected_by_user
- rejected_by_admin
- suspended_by_user
- suspended_by_admin
def full_state case [state_user, state_admin] when %w(pending pending) :nothing when %w(pending requested) :requested_by_admin when %w(requested pending) :requested_by_user when %w(requested accepted) :member when %w(requested rejected) :rejected_by_admin when %w(requested suspended) :suspended_by_admin when %w(accepted requested) :member when %w(accepted suspended) :suspended_by_admin when %w(rejected requested) :rejected_by_user when %w(suspended requested) :suspended_by_user when %w(suspended accepted) :suspended_by_user else raise UnanticipatedState end end @@@
This is /really/ hackish and cumbersome though... any thoughts?
I just thought it might help in terms of making state_machine the ubiquitous solution for ruby state handling by providing a plug-n-play solution for web app developers.
Thanks for the shout-out in the blog post btw (http://www.pluginaweek.org/2009/03/08/state_machine-one-machine-to-rule-them-all/)!
original LH ticket
This ticket has 0 attachment(s).