Rails2.1 で find_filter
あるフィルタが定義されているかどうかを知りたいとき、
Controller.find_filter は非常に便利で
1.x 時代から一部で重宝されていたが、
このたび Rails2.1 ではなくなってしまった。
これは obsoleted というより内部のクラス構成が変わってしまったことに起因する。
before 2.1
ruby>>
ApplicationController.filter_chain.class
=> Array
<<ruby
after 2.1
ruby>>
ApplicationController.filter_chain.class
=> ActionController::Filters::FilterChain
<<ruby
Controller.filter_chain は定義されたフィルタが格納されたオブジェクトであるが、これが 2.1 からは専用のFilterChainクラスに進化した。
これにより、以下のような数々のフィルタ操作メソッド
- find_filter
- append_filter_to_chain
- prepend_filter_to_chain
- ...
を直接コントローラに定義する(2.1以前)のではなく、
同クラスに持たせることができるようになった。
これは、名前空間的にも責務の明瞭化としても進化と言える。
2.1 でのフィルタの検索
従って、今後は Controller クラスに直接問い合わせるのでなく、
フィルタを管理する FilterChain インスタンスに尋ねることになる。
ruby>>
ApplicationController.filter_chain.find(:login_required)
=> #<ActionController::Filters::BeforeFilter:0x2621914 ...
<<ruby
互換性
しかしながら、未だに1.2ユーザも多いプラグインなどでは後方互換性が必要である。
色んな対応策が考えられるが、
ここでは、2.1 側に涙を飲んでもらって、
せっかく奇麗にした所を悪いが find_filter を追加させてもらう。
ruby>>
ActionController::Base.class_eval do
unless respond_to?(:find_filter)
def self.find_filter(name)
filter_chain.find(name)
end
end
<<ruby
(vendor/plugins/xxx/init.rb)