2011年12月21日水曜日

[Rails3] before_filter に条件を設定する

実行環境:
ruby 1.9.3
Rails 3.1.3
ログイン認証なんかを実現する際におなじみの before_filter に適用条件をつけてみようというお話です。

① アクション名で制限をかける
:only、:except オプションを使うと、アクション名で適用条件を設定できます。
#{RAILS_ROOT}/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base before_filter :my_filter1, :only => 'index' before_filter :my_filter2, :except => ['index', 'show'] private def my_filter1 end def my_filter2 end end
親コントローラーに設定する場合は、継承する全てのコントローラーで「参照は誰でも可、更新・削除操作はログインが必要」なんて場合には効果的に使えると思います。


② 自由な条件で制限をかける
:if、:unless オプションを使うと、もっと自由に適用条件を設定できます。
#{RAILS_ROOT}/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base before_filter :my_filter1, :if => :my_condition1? before_filter :my_filter2, :unless => :my_condition2? private def my_filter1 end def my_filter2 end def my_condition1? return true end def my_condition2? return false end end

:if や :unless の後ろはフィルタと同じようにメソッドにする必要があります。単純に true や false、あるいは真偽値を返す式を置いてもエラーではじかれてしまいます。

使い方としては、コントローラー名で判定をしたり、URL のパス文字列で判定したり、というのが一般的だと思います。

例)コントローラー名で判断する場合
#{RAILS_ROOT}/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base before_filter :my_filter, :unless => :my_condition? private def my_filter end def my_condition? self.controller_name == 'login' end end
例)URLのパス部分の文字列で判断する場合
#{RAILS_ROOT}/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base before_filter :my_filter, :if => :my_condition? private def my_filter end def my_condition? request.path_info.match(/^\/admin\//) end end

0 件のコメント:

コメントを投稿