Railsで before_action
などのフィルタでは、 only
などのオプションを追加することで対象のActionを制限できます。
8 フィルタ | Action Controller の概要 - Railsガイド
そんな中、同一の before_action
を別オプションで複数定義してしまったことがあったため、挙動をメモしておきます。
目次
環境
- Rails 6.1.4
Controllerの場合
Controllerで before_action
を実装する時、
class BeforeActionFilterController < ApplicationController before_action :set_template_value, except: [:index3] before_action :set_template_value before_action :set_template_value, only: [:index3] def index1 end def index2 end def index3 end private def set_template_value @template_value = 'foo' end end
と定義してしまったとします。
この場合は、 index3
のみ before_action
が動作します。
index1の場合
index2の場合
index3の場合
この挙動は
同じフィルタを異なるオプションで複数回呼び出しても期待どおりに動作しません。最後に呼び出されたフィルタ定義によって、それまでのフィルタ定義は上書きされます。
のためです。
Mailerの場合
Mailerにも before_action
などのコールバックがあります。
こちらも挙動は同じです。
そのため、
class BeforeActionCallbackMailer < ApplicationMailer before_action :set_template_value, except: [:welcome3] before_action :set_template_value before_action :set_template_value, only: [:welcome3] def welcome1 mail(to: 'welcome1@example.com') end def welcome2 mail(to: 'welcome2@example.com') end def welcome3 mail(to: 'welcome3@example.com') end private def set_template_value @template_value = 'bar' end end
というMailerを使い
class BeforeActionFilterController < ApplicationController def send_mail BeforeActionCallbackMailer.welcome1.deliver_now BeforeActionCallbackMailer.welcome2.deliver_now BeforeActionCallbackMailer.welcome3.deliver_now end
のようにメールを送信したとします。
この場合も、 welcome3
のみ before_action
が動作しテンプレートに値が渡されます。
welcome1の場合
welcome2の場合
welcome3の場合
ソースコード
Githubに上げました。
https://github.com/thinkAmi-sandbox/rails_miscellaneous_app
今回のプルリクはこちらです。
https://github.com/thinkAmi-sandbox/rails_miscellaneous_app/pull/1