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

时间:2016-02-23 21:54:23

标签: ruby-on-rails callback controllers

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

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

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

1 个答案:

答案 0 :(得分:8)

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

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

用法:

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可以是通用的,并且是几个控制器共享代码片段的示例,例如从数据库检索记录,执行特定操作(如果用户不是管理员时重定向等),您可以创建文件夹{{ 1}}包含控制器的每个共享代码段(如果是这样,请不要忘记在模块定义+ lib/controllers/语句中将模块重命名为Controllers::CleanUserColumnsAfterAction
  • 选项#2涉及在lib /中定义的文件,它不会像开发环境那样像其他文件一样重新加载。这意味着在您的应用上测试新代码之前,您需要重新启动服务器。