とりあえずトップページだけ作ってみます(その 2)。
前回に引き続き今日は、
- mixlone の Controller 機能を集約する Main Controller の作成
- 認証情報(ひとの情報)を格納する Person Model の作成
- ログイン処理をする login Action の実装
- ログイン済みか確認しログインしていなければログインページへリダイレクトする before Filter の実装と設定
の残り 3 と 4 を実装します。
login Action では以下の処理を行うことにします。
- ログインフォームの表示 – メールアドレスとパスワードを入力するフォームを表示します。下には“ログイン”ボタンがあり、これを押すと login Action 自身へ POST されるようにします。
- ログイン処理の実施 – POST されたメールアドレスとパスワードに一致する Person が存在するか確認します。一致する Person が存在する場合は session[:person_id] に Person の id を格納し home Action へリダイレクトします。一致する Person が存在しない場合はエラーメッセージを表示します。
まずはログインフォームの準備から始めましょう。
http://(サーバの IP アドレス):3000/main/login へアクセスした際に表示されるのは app/views/main/login.rhtml でした。これを以下の通り変更します。
FILE: app/views/main/login.rhtml 1 <h1>Main#login</h1> 2 <p><%= flash[:login] %></p> 3 <%= start_form_tag %> 4 <p><label for="person_email_address">Email address</label><br/> 5 <%= text_field 'person', 'email_address' %></p> 6 <p><label for="person_password">Password</label><br/> 7 <%= password_field 'person', 'password' %></p> 8 <%= submit_tag 'LOGIN' %> 9 <%= end_form_tag %>
続いて login Action の Action メソッドを修正します。
http://(サーバの IP アドレス):3000/main/login へアクセスした際に実行されるのは app/controllers/main_controller.rb で定義された login メソッドでした。これを以下の通り変更します。
FILE: app/controllers/main_controller.rb 1 class MainController < ApplicationController 2 model :person 3 4 def home 5 end 6 7 def login 8 if request.post? then 9 person = Person.find(:first, :conditions => [ 'email_address = :email_address and password = :password', params[:person]]) 10 if person then 11 session[:person_id] = person[:id] 12 redirect_to :action => :home 13 else 14 flash[:login] = 'LOGIN ERROR' 15 end 16 end 17 end 18 end
http request が POST かどうか調べています(8 行目)。もし POST であれば 9 行目から 15 行目までを実行します。
POST であれば Person モデルで email_address と password がフォームから入力されたものと一致するオブジェクトがないか探します(9 行目)。一致するものがあれば Person オブジェクトが返され、なければ nil が返されます。
person に値が入っているか(nil かどうか)確認します(10 行目)。もし値が入っていれば person オブジェクトの :id を session[:person_id] に代入し(11 行目) home Action へリダイレクトします(12 行目)。person が nil なら flash[:login] にエラーメッセージを代入します(14 行目)。
Action メソッドを実行するまえに実行したい処理をメソッドとして定義し before Filter として設定することができます。同じように Action メソッド実行のあとに実行したい処理を after Filter として設定することができます。ついでに before と after をペアで around Filter として設定することもできます。
“session[:person_id] がセットされているかを確認しセットされていなかったら login Action へリダイレクトする”というメソッドを用意し before Filter に設定することでログインしないとコンテンツを閲覧できないように制限することが出来ます。
app/controllers/main_controller.rb を以下の通り修正します。
FILE: app/controllers/main_controller.rb 1 class MainController < ApplicationController 2 model :person 3 before_filter :authorize, :except => :login 4 5 def home 6 end 7 8 def login ... 18 end 19 20 private 21 def authorize 22 unless session[:person_id] then 23 redirect_to :action => :login 24 end 25 end 26 end
authorize という private なメソッドを定義し(20 行目 〜 25 行目)、before_filter で Main Controller にアタッチしています(3 行目)。ただし login Action に関しては before_filter の対象から外さなければならないので :except オプションで対象外としています(そうしないと無限リダイレクトにはまってしまいます)。
script/server を起動し意図した通り動作するか確認しましょう。
とりあえず、今日はここまで。
