Ruby on Rails - запуск кода обратного вызова после инициализации метода в классе - PullRequest
0 голосов
/ 16 октября 2018

Я использую 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 method.

Для этого я создал декоратор (например: 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 голосов
/ 17 октября 2018

Rails использует фильтры before, after и around _action только на "действиях" .Контроллеры Restfull должны определять только 7 действий :

  1. show
  2. index
  3. edit
  4. update
  5. new
  6. create
  7. destroy

Обычно контроллеры не определяют действие initialize, хотя они наследуют метод initialize от своего родительского класса,То есть в рельсах нет маршрута, который будет использовать метод инициализации контроллера.Поскольку при открытии действия index Spree::Admin::ReportsController не выполняется initialize, фильтр post_initialize никогда не запускается.

Rails не имеет обратного вызова after_initialize для своих контроллеров, только для его моделей,Если вы хотите добавить код в функцию инициализации контроллера, вы можете открыть класс заново и перезаписать инициализатор (не рекомендуется) или создать подкласс контроллера, вызвать 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 под капотом .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...