before_filterで認証処理をかく

よく認証処理のサンプルで、ApplicationControllerで以下の様に記述する例がある。

class ApplicationController < ActionController::Base
  # 各々のコントローラが動作する前に動くメソッドを指定(今回はauthenticate)
  before_filter :authenticate, :except => :login
  def authenticate
    # 認証処理
    # 認証できなかったらログイン画面に飛ばす
  end
end

実際のログイン画面はLoginControllerのloginメソッドから起動されるものとする。
ここで重要なのは:exceptで:loginアクションの場合はこのフィルタを実行しないように指定していること。これの記述がないとLoginControllerのloginアクションが呼び出される場合もauthenticateメソッドが実行され、永久ループとなってしまう。
で、ここでは、:exceptでloginメソッドを除外しているわけ。しかし、これって他のコントローラにもloginっていうメソッドがあったら(ないと思うけど)そいつに対してもauthenticateメソッドが実行されてしまう。

そんなことはないだろうけど誰かがこれを知らずにうっかりloginなんてメソッドを書いたら認証が通らなくなってしまう機能ができるのはいやだ。できれば、基本的に全機能に認証をかけて必要なものだけかけないっての言うのが望ましい。
と思っていたら、そういうことを実現できるメソッドがあった。
これは、フィルタをかけたくないアクションのあるコントローラの中に書く。
ほぼ全部の画面に認証をかけて、認証をかけないのはログイン画面だけってときには、こっちの方がいいかも。(ちなみにのときApplicationControllerの:except => :loginは不要)

class LoginController < ApplicationController
  # このコントローラは認証処理をスキップする。スキップしたくない場合は:exceptを使ってアクションを指定。
  skip_filter :authenticate
  def login
    # ログイン画面に遷移
  end
end

詳細は以下のページで。
http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html