読者です 読者をやめる 読者になる 読者になる

どこでも見れるメモ帳

ちょっとした備忘録を無秩序に投稿します.気軽にコメントください^^

before_filterをすべてスキップする


はじめに

子クラスで親クラスのbefore_filterをすべて実行させたくない状況が生じたのでメモ。

やりかた

skip_before_filter(*_process_action_callbacks.select{|filter| filter.kind == :before}.map(&:filter))

まず、skip_before_filterは、フィルタのシンボルを渡すとスキップできる。*1
フィルタのシンボルは、_process_action_callbacksから抜き出す。*2 *3
これは配列で返ってくるので、*で配列の展開をしている。*4

おまけ

子クラスのbefore_filterを先に実行し、その後に親クラスのbefore_filterを実行するには?
before_filterは、引数の順序にしたがって実行される。
よって、子の後に親を実行するには、1)親クラスのbefore_filterをすべてスキップし、2)子クラスのbefore_filterを実行し、3)親クラスのbefore_filterを実行すれば良い。
具体的には以下のとおり。

super_before_filters = _process_action_callbacks.select{|filter| filter.kind == :before}.map(&:filter)
skip_before_filter *super_before_filters
before_filter :child_before_filter, *super_before_filters

同じ考え方で、子クラスのbefore_filterを親クラスのbefore_filterの合間に実行したり、親クラスのbefore_filterを部分的に実行したりできる。

広告を非表示にする