Ruby on Rails - 运行 class 初始化方法后的回调代码

Ruby on Rails - Run callback code after initialize method in class

我在 Rails 5.2 和 ruby 2.4.2p198

上使用 Ruby

假设我有一个控制器(例如这个:https://github.com/spree/spree/blob/3-6-stable/backend/app/controllers/spree/admin/reports_controller.rb),我想 运行 在 initialize 方法之后使用回调的一些代码。

为此,我创建了一个装饰器(例如:reports_controller_decorator.rb)并在 after_action 回调中添加了我想要 运行 的方法。

我的问题是,如果我在 index 方法上使用回调,这会起作用(调用该方法),但如果我将 initialize 方法作为参数传递,它就不起作用回调:

# It works (note the index method in the callback parameter)
Spree::Admin::ReportsController.class_eval do
  after_action :post_initialize, only: :index

  def post_initialize
    Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
  end
end
# It doesn't (note the initialize method in the callback parameter)
Spree::Admin::ReportsController.class_eval do
  after_action :post_initialize, only: :initialize

  def post_initialize
    Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
  end
end

我做错了什么?在 initialize 方法之后可以 运行 回调吗?

Rails 仅在 "actions". Restfull controllers should only define 7 actions:

上使用 beforeafteraround _action 过滤器
  1. 显示
  2. 指数
  3. 编辑
  4. 更新
  5. 创建
  6. 摧毁

通常控制器不会定义 initialize 操作,尽管它们确实从其父 class 继承了 initialize 方法。也就是说 rails 中没有路由会去到控制器的初始化方法。由于当您打开 Spree::Admin::ReportsControllerindex 操作时没有 运行 的 initialize 操作,因此 post_initialize 过滤器永远不会 运行.

Rails 没有针对其控制器的 after_initialize 回调,仅针对其模型。如果您想将代码添加到控制器的初始化函数中,您可以重新打开 class 并覆盖初始化程序(不推荐)或子 class 控制器并在新的初始化程序中调用 super 并添加您的代码后记.

Spree::Admin::ReportsController.class_eval do
  def initialize
    super
    Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
  end
end

class CustomSalesTotalController < Spree::Admin::ReportsController
  def initialize
    super
    Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
  end
end

Spree 实际上就是这么做的under the hood