的Rails 4.2 紅寶石2.3調用deliver_later之前保存當前的可選路徑範圍軌郵件
我有兩個可選路由與區域信息範圍。它們在配置default_url_options方法的application_controller
中設置爲before_action
。即
# 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的執行方法接受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