Запуск ваших почтовых программ в жизненном цикле модели не рекомендуется ИМХО. Рекомендуемый подход заключается в том, чтобы запускать почтовые программы с контроллера.
Если вы хотите добиться разделения проблем в контроллере и не загрязнять ваш код контроллера почтовыми вызовами, вы можете использовать комбинацию ActiveSupport::Notifications
и контроллер after_filter
, чтобы извлечь логику почтовой программы в свой собственный модуль.
module MailerCallbacks
module ControllerExtensions
def self.included(base)
base.after_filter do |controller|
ActiveSupport::Notifications.instrument(
"mailer_callbacks.#{controller_path}##{action_name}", controller: controller
)
end
end
end
module Listener
def listen_to(action, &block)
ActiveSupport::Notifications.subscribe("mailer_callbacks.#{action}") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
controller = event.payload[:controller]
controller.instance_eval(&block)
end
end
end
end
Давайте предположим, что вы хотите, чтобы реорганизовать следующий контроллер, используя наш модуль, созданный ранее:
class PostsController < ApplicationController
def create
@post = Post.new permitted_params
respond_to do |format|
if @post.save
PostMailer.notify(@post).deliver
format.html { redirect_to @post, notice: 'Successfully created Post' }
else
format.html { render action: 'new' }
end
end
end
end
Выполните следующие действия:
Создать инициализатор зарегистрировать расширения контроллера:
# config/initializers/mailer_callbacks.rb
ActiveSupport.on_load(:action_controller) do
include MailerCallbacks::ControllerExtensions
end
В том же или отдельном инициализаторе, создать класс и расширить Listener
модуль зарегистрировать обратные вызовы:
# config/initializers/mailer_callbacks.rb
class MailerListeners
extend MailerCallbacks::Listener
# register as many listeners as you would like here
listen_to 'posts#create' do
PostMailer.notify(@post).deliver if @post.persisted?
end
end
Удалить код почтовой программы из контроллера.
class PostsController < ApplicationController
def create
@post = Post.new permitted_params
respond_to do |format|
if @post.save
format.html { redirect_to @post, notice: 'Successfully created Post' }
else
format.html { render action: 'new' }
end
end
end
end
По сути, мы создали наблюдателя на действия контроллера и зарегистрировали наши рассыльщика обратные вызовы с контроллером вместо привязки его к модели жизненного цикла. Я лично считаю этот подход более чистым и более простым в управлении.
Кто-нибудь знает, как это сделать в rails admin? – icemelt