Rails 4.2 Руби 2,3Сохранение текущего дополнительного охвата маршрута перед вызовом deliver_later на рельсах Мейлер
У меня есть два дополнительных маршрутизации областей, относящиеся к местности информации. Они установлены в before_action
в application_controller
, который настраивает метод default_url_options. т.е.
# app/controllers/application_controller
# simplified version, usually has two locale values,
# locale_lang and locale_city
before_action :redirect_to_locale_unless_present
private
# If params[:locale] is not set then
# redirect to the correct locale base on request data
def redirect_to_locale_unless_present
unless params[:locale].present?
redirect_to url_for(locale: request.location.country_code)
end
end
def default_url_options(options = {}
{ locale_lang: params[:locale_lang] }.merge(options)
end
В прицелы locale_lang
и locale_city
, которые в конечном итоге выглядит что-то вроде http://localhost:3000/fr/ или http://localhost:3000/en/
Это все работает, как предполагалось в браузере, однако я хотел бы использовать ActionMailer :: DeliveryJob для отправки писем в фоновых процессах. Очевидная проблема заключается в том, что ActionMailer :: DeliveryJob не сохраняет значение params[:locale]
.
Я хотел был бы иметь возможность позвонить SomeMailer.generic_email(options).deliver_later
и отправить это сообщение default_url_options
в ActionMailer :: DeliveryJob, который затем передаст их по цепочке и будет использовать их при фактической обработке почты. Я мог бы, конечно, определить default_url_options в качестве параметра для каждого метода Mailer, но я бы скорее настроил приложение, чтобы оно было автоматически включено.
Вы когда-нибудь сталкивались с этой проблемой или имели какие-либо предложения о том, как подойти к задаче. Имейте в виду, что он также должен быть потокобезопасным.
Мои в настоящее время подход заключается в отсутствии, чтобы сохранить текущий запрос в Thread.current, а затем получить те, когда enqueue_delivery вызывается через .deliver_later. то я хотел, чтобы переопределить ActionMailer :: DeliveryJob «s выполнить метод принять url_options и использовать class_eval для определения default_url_options метода в классе тока мэйлера. Однако выполнение не кажется даже вызванным при использовании deliver_later любых идей?
class ApplicationController
before_action :store_request
private
def store_request
Thread.current['actiondispatch.request'] = request
end
end
module DeliverLaterWithLocale
module MessageDeliveryOverrides
def enqueue_delivery(delivery_method, options={})
args = [
@mailer.name,
@mail_method.to_s,
delivery_method.to_s,
url_options,
*@args
]
ActionMailer::DeliveryJob.set(options).perform_later(*args)
end
private
def url_options
options = {}
request = Thread.current["actiondispatch.request"]
if request
host = request.host
port = request.port
protocol = request.protocol
lang = request.params[:locale_lang]
city = request.params[:locale_city]
standard_port = request.standard_port
options[:protocol] = protocol
options[:host] = host
options[:port] = port if port != standard_port
options[:locale_lang] = lang
options[:locale_city] = city
end
ActionMailer::Base.default_url_options.merge(options)
end
end
module DeliveryJobOverrides
def perform(mailer, mail_method, delivery_method, url_options, *args)
mailer = mailer.constantize.public_send(mail_method, *args)
Kernel.binding.pry
mailer.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def default_url_options_with_options(*args)
default_url_options_without_current_request(*args).merge(url_options)
end
alias_method_chain :default_url_options, :options
RUBY
mailer.send(delivery_method)
end
end
end