以下のコードは、before_filters が異なる順序で追加された 2 つのコントローラーを示しています。その結果、コントローラーの動作が異なります。
current_user が nil (ログアウト) の場合:
- FooController -> login_path にリダイレクト
- BarController -> root_path にリダイレクト
もちろん、この 2 つの方法を組み合わせてよりスマートにして、この特定の例をなくすこともできますが、それではこの質問の要点が抜けています。
当面の問題は、ActionController では、フィルターが追加される順序が関連しているということです。(その実装は最高ではないと主張することもできますが、それがその方法です-それで先に進みましょう)
それがActionControllerの仕組みなので、その動作をテストしたいと思います。ただし、個々のアクション (DRY ではない) ごとに before フィルターの結果をテストする必要はありません。私が把握できる限り、実際に重要なのは、各アクションのフィルター チェーンの結果の順序です。
実際に行う唯一のことbefore_filter :require_user
は、アイテムをコールバック チェーンに挿入することです。追加のアイテムがチェーンに追加されたことをサブクラスでテストする必要があるのはそれだけです。require_user
アクションが及ぼす影響をテストする必要はありません。
とはいえ、お金の問題は次のとおりです。特定のコントローラーとアクションのフィルター チェーンにあるメソッドを返すパブリック API はありますか? これには、フィルタの前、後、および前後を適切な順序で含める必要があります。
class ApplicationController < ActionController::Base
def require_user
unless current_user
redirect_to login_path and return
end
end
def require_admin
unless current_user.try(:admin?)
redirect_to root_path and return
end
end
end
class FooController < ApplicationController
before_filter :require_user
before_filter :require_admin
end
class BarController < ApplicationController
# reverse the order of the filters
before_filter :require_admin
before_filter :require_user
end