Allow delivery method options to be set per mail instance

This commit is contained in:
Aditya Sanghi 2012-08-20 18:52:12 +05:30
parent 27acd1e0d2
commit 8fc8763fde
4 changed files with 58 additions and 3 deletions

View File

@ -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*

View File

@ -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)

View File

@ -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

View File

@ -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