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/ 中定义的文件,它不会像其他文件一样由您的开发环境重新加载。这意味着在您的应用程序上测试新代码之前,您需要重新启动服务器。
登录后,我有我的 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/ 中定义的文件,它不会像其他文件一样由您的开发环境重新加载。这意味着在您的应用程序上测试新代码之前,您需要重新启动服务器。