Ruby on Rails-在类中的initialize方法之后运行回调代码

时间:2018-10-16 20:04:55

标签: ruby-on-rails ruby callback spree

我正在将Ruby on Rails 5.2和ruby 2.4.2p198一起使用

假设我有一个控制器(例如: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方法之后运行回调吗?

1 个答案:

答案 0 :(得分:0)

Rails仅在"actions"上使用beforeafteraround _action过滤器。 Restfull控制器应只定义7个actions

  1. 显示
  2. 索引
  3. 编辑
  4. 更新
  5. 创建
  6. 破坏

尽管控制器确实从其父类继承了initialize方法,但通常不会定义initialize动作。也就是说,rails中没有路由可用于控制器的initialize方法。由于打开initialize的{​​{1}}操作时没有index操作要运行,因此Spree::Admin::ReportsController过滤器将永远不会运行。

Rails的控制器没有after_initialize回调,只有其模型没有。如果要将代码添加到控制器的初始化函数中,则可以重新打开该类并覆盖初始化器(不推荐使用)或对控制器进行子类化,然后在新的初始化器中调用super并为您添加代码后缀。

post_initialize

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

实际上Spree在做什么under the hood