0

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 

Antwort

1

Incase jemand anderes möchte dies tun. Ich kann es fixiert

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 
     mailer.default_url_options = url_options 
     mailer.public_send(mail_method, *args).send(delivery_method) 
    end 
    end 
end 

Hinzufügen Und dann schreibe diese an die jeweiligen Klassen in einer initializer