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

Rails - Call same after_action method from different controllers

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

只需将相同的代码复制并粘贴到两个控制器中就足够简单了,但我知道有一天我会在一个控制器中进行更改而忘记更新另一个。

有什么方法可以从不同的控制器调用与 after_action 相同的方法吗?

有几种方法可以满足您的需求:

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

方案一:ApplicationController中的一个方法

实施:

class ApplicationController < ActionController::Base
  # ...

  def clean_user_columns
    raise 'No user connected!' unless current_user.present?
    do_some_stuff
  end

用法:

class SessionsController < ApplicationController
  after_action :clean_user_columns

选项 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

用法:

class SessionController < ApplicationController
  include CleanUserColumnsAfterAction
  after_action :clean_user_columns

结论:在我看来,选项 #2 是可行的方法:

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