Reputation: 161
I am using Ruby on Rails 5.2 with ruby 2.4.2p198
Let's say I have a controller (for example this: https://github.com/spree/spree/blob/3-6-stable/backend/app/controllers/spree/admin/reports_controller.rb) and I want to run some code using a callback after the initialize
method.
For this, I've created a decorator (for example: reports_controller_decorator.rb
) and added the method that I want to run in the after_action
callback.
My issue is that this works (the method is called) if I use the callback on the index
method, but it doesn't work if I pass the initialize
method as parameter in the callback:
# 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
What am I doing wrong? Is possible to run callbacks after the initialize
method?
Upvotes: 1
Views: 2597
Reputation: 1171
Rails uses the before
, after
and around
_action
filters only on "actions". Restfull controllers should only define 7 actions:
Usually controllers don't define an initialize
action, although they do inherit an initialize
method from their parent class. That is to say there is no route in rails that will go to the initialize method of a controller. Since there is no initialize
action to run when you open the index
action of Spree::Admin::ReportsController
the post_initialize
filter is never run.
Rails has no after_initialize callback for its controllers, only for its models. If you want to add code to the initialize function of the controller you can reopen the class and overwrite the initializer (not recomended) or subclass the controller and call super in the new initializer and add you code afterwords.
Spree::Admin::ReportsController.class_eval do
def initialize
super
Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
end
end
or
class CustomSalesTotalController < Spree::Admin::ReportsController
def initialize
super
Spree::Admin::ReportsController.add_available_report!(:custom_sales_total)
end
end
Which is actually what Spree is doing under the hood.
Upvotes: 1