acts_as_state_machine

吉見和也(Kazuya Yoshimi) 2008-04-10 21:38:46

restful_authenticationのジェネレータには、「--stateful」というオプションがあって、acts_as_state_machineというプラグインを使ったユーザの状態管理をサポートしています。


./script/generate authenticated user sessions --stateful

これをやると、アクティベーションの部分も一緒に入りますので、出来上がるものは以下と全く同じ。


./script/generate authenticated user sessions 

              --include-activation 

              --stateful

acts_as_state_machineはインストールされませんので、別途インストール


$ script/plugin install http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/

ジェネレートした後でuser.rbを見てみると、いつものに加えてacts_as_state_machine用の記述がいくつかある


acts_as_state_machine :initial => :pending

  state :passive

  state :pending, :enter => :make_activation_code

  state :active,  :enter => :do_activate

  state :suspended

  state :deleted, :enter => :do_delete

  event :register do

    transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) }

  end

  event :activate do

    transitions :from => :pending, :to => :active 

  end

  event :suspend do

    transitions :from => [:passive, :pending, :active], :to => :suspended

  end

  event :delete do

    transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted

  end

  event :unsuspend do

    transitions :from => :suspended, :to => :active,  :guard => Proc.new {|u| !u.activated_at.blank? }

    transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? }

    transitions :from => :suspended, :to => :passive

  end

最初のacts_as_state_machineではデフォルトの状態を設定。

stateで状態の種類、eventで状態遷移のメソッド(実際に呼ぶ時はけつに!をつける)を定義しています。

DBでのデフォルトはpassiveで、acts_as_state_machineで指定してるのはpending

基本的には保存前がpassiveで、保存時に自動でpendingになる。

状態が他の状態からかわる時、:enterで指定されたメソッドが実行されるので、ここではmake_activation_codeというメソッドが実行されます。

この時event :registerが定義されていますので、saveじゃなくてregister!メソッドでも同じ動作はするんですが、eventで定義したメソッドはバリデーションがかかりません。なので、必要なデータが入ってなくても普通に保存できてしまうのが難点。:guardを設定することで、パスワードが入っていない時はpendingにはならないようになっているけど、保存自体はされるのでpassiveのままレコードが出来てしまう。こんなのゴミデータ以外のなにものでもない

なので思い切ってevent :register do~endは削っちゃいましょう。unsuspendのところが微妙におかしくなるけど、ここもあわせて書き換えておけば安心です。

acts_as_state_machineはなかなか面白いプラグインなんですが、usersテーブルにactivation_codeが入るのがいやなので、実際に使ってる時は原型をとどめないくらいに作り直しちゃってます。

2007-02-15ARで状態管理したい(acts_as_state_machine)を参考にさせていただきました。

押忍

※このエントリはZDNetブロガーにより投稿されたものです。朝日インタラクティブ および ZDNet編集部の見解・意向を示すものではありません。

SpecialPR