From 8fc8763fde2cc685ed63fcf640cfae556252809b Mon Sep 17 00:00:00 2001 From: Aditya Sanghi Date: Mon, 20 Aug 2012 18:52:12 +0530 Subject: [PATCH] Allow delivery method options to be set per mail instance --- actionmailer/CHANGELOG.md | 16 ++++++++ actionmailer/lib/action_mailer/base.rb | 2 +- .../lib/action_mailer/delivery_methods.rb | 4 +- actionmailer/test/delivery_methods_test.rb | 39 +++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index c33a24c1ba..45ff9eab1a 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,5 +1,21 @@ ## Rails 4.0.0 (unreleased) ## +* Allow delivery method options to be set per mail instance *Aditya Sanghi* + + If your smtp delivery settings are dynamic, + you can now override settings per mail instance for e.g. + + def my_mailer(user,company) + mail to: customer.email, subject: "Welcome!", + delivery_method_options: {user_name: company.smtp_user, + password: company.smtp_password} + end + + This will ensure that your default SMTP settings will be overridden + by the company specific ones. You only have to override the settings + that are dynamic and leave the static setting in your environment + configuration file (e.g. config/environments/production.rb) + * Allow to set default Action Mailer options via `config.action_mailer.default_options=` *Robert Pankowecki* * Raise an `ActionView::MissingTemplate` exception when no implicit template could be found. *Damien Mathieu* diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index f5c325179f..4a099553c0 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -683,7 +683,7 @@ module ActionMailer #:nodoc: m.charset = charset = headers[:charset] # Set configure delivery behavior - wrap_delivery_behavior!(headers.delete(:delivery_method)) + wrap_delivery_behavior!(headers.delete(:delivery_method),headers.delete(:delivery_method_options)) # Assign all headers except parts_order, content_type and body assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path) diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 3b38dbccc7..b795d4f80a 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -57,7 +57,7 @@ module ActionMailer self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze end - def wrap_delivery_behavior(mail, method=nil) #:nodoc: + def wrap_delivery_behavior(mail, method=nil, options=nil) #:nodoc: method ||= self.delivery_method mail.delivery_handler = self @@ -66,7 +66,7 @@ module ActionMailer raise "Delivery method cannot be nil" when Symbol if klass = delivery_methods[method] - mail.delivery_method(klass, send(:"#{method}_settings")) + mail.delivery_method(klass,(send(:"#{method}_settings") || {}).merge!(options || {})) else raise "Invalid delivery method #{method.inspect}" end diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 08f84dbf3b..7109f23e4c 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -4,6 +4,13 @@ require 'mail' class MyCustomDelivery end +class MyOptionedDelivery + attr_reader :options + def initialize(options) + @options = options + end +end + class BogusDelivery def initialize(*) end @@ -115,6 +122,38 @@ class MailDeliveryTest < ActiveSupport::TestCase assert_instance_of Mail::TestMailer, email.delivery_method end + test "delivery method options default to class level options" do + default_options = {a: "b"} + ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options + mail_instance = DeliveryMailer.welcome(:delivery_method => :optioned) + assert_equal default_options, mail_instance.delivery_method.options + end + + test "delivery method options can be overridden per mail instance" do + default_options = {a: "b"} + ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options + overridden_options = {a: "a"} + mail_instance = DeliveryMailer.welcome(:delivery_method => :optioned, :delivery_method_options => overridden_options) + assert_equal overridden_options, mail_instance.delivery_method.options + end + + test "default delivery options can be overridden per mail instance" do + settings = { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true } + assert_equal settings, ActionMailer::Base.smtp_settings + overridden_options = {user_name: "overridden", :password => "somethingobtuse"} + mail_instance = DeliveryMailer.welcome(:delivery_method_options => overridden_options) + delivery_method_instance = mail_instance.delivery_method + assert_equal "overridden", delivery_method_instance.settings[:user_name] + assert_equal "somethingobtuse", delivery_method_instance.settings[:password] + assert_equal delivery_method_instance.settings.merge(overridden_options), delivery_method_instance.settings + end + test "non registered delivery methods raises errors" do DeliveryMailer.delivery_method = :unknown assert_raise RuntimeError do