Rails 4.2 Rubin 2.3aktuellen optionale Route Umfang Speicher vor dem Aufruf deliver_later auf Schienen Mailer
Ich habe zwei Bereiche in Bezug auf locale Informationen optional Routing. Sie werden in einer before_action
in der application_controller
festgelegt, die die Methode default_url_options konfiguriert. dh
# 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
Die Bereiche sind locale_lang
und locale_city
, die so etwas wie http://localhost:3000/fr/ am Ende der Suche oder http://localhost:3000/en/
Das alles funktioniert wie im Browser gedacht, aber würde Ich mag Action nutzen :: DeliveryJob E-Mails in Hintergrundprozessen senden. Das offensichtliche Problem ist, dass ActionMailer :: DeliveryJob den Wert params[:locale]
nicht speichert.
Ich würde gerne SomeMailer.generic_email(options).deliver_later
anrufen können und dies senden die aktuelle default_url_options
an den ActionMailer :: DeliveryJob, die dann diese entlang der Kette übergeben und sie bei der tatsächlichen Verarbeitung der Mail verwenden würde. Ich könnte natürlich default_url_options als Parameter für jede Mailer-Methode definieren, aber ich würde die App lieber so einrichten, dass sie automatisch eingebunden wird.
Haben Sie jemals dieses Problem oder Vorschläge zur Vorgehensweise kennengelernt? Beachten Sie, dass es auch threadsicher sein sollte.
Mein zur Zeit versagt Ansatz ist es, die aktuellen Anfrage in Thread.current zu speichern und dann diejenigen abzurufen, wenn enqueue_delivery über genannt wird .deliver_later. Ich wollte dann Action :: DeliveryJob ‚s ausführen Methode außer Kraft zu setzen, die url_options und verwenden class_eval zu definieren, die default_url_options Methode innerhalb des aktuellen Mailer Klasse zu akzeptieren. Allerdings scheint nicht einmal aufgerufen werden, wenn deliver_later irgendwelche Ideen?
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