benzelano / test_lh_import

1 stars 0 forks source link

"normal" membership state generator #117

Closed benzelano closed 13 years ago

benzelano commented 13 years ago

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).

benzelano commented 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.

benzelano commented 13 years ago

Closing as resolved. Feel free to re-open the ticket if you create other examples or simply send a pull request on github. Thanks!