我正在将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
方法之后运行回调吗?
答案 0 :(得分:0)
Rails仅在"actions"上使用before
,after
和around
_action
过滤器。 Restfull控制器应只定义7个actions:
尽管控制器确实从其父类继承了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。