Rails - 从不同的控制器调用相同的after_action方法

Ray*_*d R 5 ruby-on-rails callback controllers

登录后,我让我的SessionsController运行after_action来重置某些用户列.在另一个控制器中,我想在创建和更新时执行相同的after_action.

将相同的代码复制并粘贴到两个控制器中都很容易,但我知道有一天我会在一个控制器中进行更改而忘记更新另一个控制器.

有没有办法从不同的控制器调用与after_action相同的方法?

MrY*_*iji 9

有几种方法可以做你想要的:

  • 选项1:在ApplicationController中定义一个方法,并使用after_action回调调用此方法
  • 选项2:在lib /文件夹中定义一个模块,将其包含在控制器中并在after_action回调中调用其方法
  • 可能是其他选择

选项1:ApplicationController中的方法

执行:

class ApplicationController < ActionController::Base
  # ...

  def clean_user_columns
    raise 'No user connected!' unless current_user.present?
    do_some_stuff
  end
Run Code Online (Sandbox Code Playgroud)

用法:

class SessionsController < ApplicationController
  after_action :clean_user_columns
Run Code Online (Sandbox Code Playgroud)

选项2:控制器中包含的模块

执行:

# file created here: /lib/clean_user_columns_after_action.rb
# you will need to restart your server to see the changes of this file
module CleanUserColumnsAfterAction
  def clean_user_columns
    do_some_stuff
  end
end
Run Code Online (Sandbox Code Playgroud)

用法:

class SessionController < ApplicationController
  include CleanUserColumnsAfterAction
  after_action :clean_user_columns
Run Code Online (Sandbox Code Playgroud)

结论:在我看来,选项#2是要走的路:

  • 选项#1涉及您的clean_user_columns可用于您应用的每个控制器,但它仅在被调用时使用.与选项#2相比,它为您节省了一行代码,即include CleanCleanUserColumnsAfterAction行.
  • 选项#2使您可以在其中包含要使用它的模块,而不是为应用程序的每个控制器提供.
  • 选项#2可以是通用的,并且是几个控制器共享代码片段的示例,例如从数据库检索记录,执行特定操作(如果用户不是管理员时重定向)等.您可以创建一个文件夹lib/controllers/来包含每个共享片段您的控制器的代码(如果是这样,请不要忘记将模块重命名Controllers::CleanUserColumnsAfterAction为模块定义+ include语句).
  • options#2涉及lib /中定义的文件,开发环境不像其他文件那样重新加载.这意味着在您的应用上测试新代码之前,您需要重新启动服务器.