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編集部の見解・意向を示すものではありません。