使用从任何邮件程序内部调用的方法覆盖 ActionMailer 默认值
Override ActionMailer defaults with a method called from inside any mailer
鉴于我们在 application.rb 中设置了自定义 header 作为
config.action_mailer.default_options = {
'X-MyCustomHeader' => "Default_value" }
我希望能够从任何邮件程序中调用方法,例如 remove_custom_header
,并且它已删除 header,或者至少设置为 nil。
因为它是自定义 header(以 X- 开头)ActionMailer 将允许创建多个,而不是像使用标准 headers 那样重置它。
定义可以覆盖它的方法的最佳方法是什么?
我遇到的问题是你在邮件方法中调用 headers['X-MyCustomHeader'] = nil
它不会覆盖它,它只是创建第二个 header,其中条目为 nil,而原始的来自 application.rb 在电子邮件中。
我能找到的覆盖默认设置的唯一方法是在 ApplicationMailer(或任何继承邮件程序 class')中调用 default 'X-MyCustomHeader' => nil
,如下所示,但不是在方法中.
class ApplicatioMailer < ActionMailer::Base
helper :application
default 'X-MyCustomHeader' => nil
end
但我想在方法的基础上调用它,而不是在邮件程序 class 本身中调用它,因为该应用程序有很多邮件程序 classes 并且我希望将其禁用一两个一些 Mailers 中的方法。
我目前的解决方案是:
class ApplicatioMailer < ActionMailer::Base
helper :application
default 'X-MyCustomHeader' => Proc.new { @is_disabled ? nil : Rails.config.action_mailer.default_header }
def remove_custom_header
@is_disabled = true
end
end
这似乎有效,因为您正在使用来自 ActionMailer 的 default
调用来覆盖。现在我已经对此进行了测试,它确实适用于多个调用,因此 @is_disabled
的值似乎不会在邮件程序调用之间持续存在。我不明白 class var 在这里是如何工作的,在调用它的邮件程序的超类中,当没有创建 class 的新 object 时,但它似乎每个新的都是空的调用 ApplicationMailer,所以对我来说它有效。然而,这是一个好的解决方案吗?我错过了一些明显的东西吗?在这种情况下使用 class var 我觉得不舒服,但我可以想出另一种方法!
在此先感谢您的帮助!
编辑::例如,我想像这样调用我的邮件程序..
class MyMailer < ApplicatioMailer
def mail_method_one(email)
# my call
remove_custom_header
mail from: a.format, subject: email.subject
end
end
而且如果我上面设置 class var 的方法是有效和健全的(我有点怀疑)有人可以解释为什么我会感兴趣它是如何工作的并且必须证明它对我的领导开发! :)
与其看起来的相反,@is_disabled
不是 class 变量,它是一个实例变量。正如你定义的方法被定义为一个实例class
请注意,您正在做...
def mail_method_one(email)
...不是...
def self.mail_method_one(email)
您可以通过使用 pry
gem 或其他检查工具停止执行来自行确认...
def mail_method_one(email)
binding.pry
如果你检查 self
你会发现你在邮件程序的一个实例中。
您确实将其称为 class 方法,但那是因为操作邮件程序使用 method_missing 来测试缺少的 class 方法是否实际上是一个实例方法并创建一个新实例MessageDelivery 传递 class 名称、方法名称和参数,随后在邮件程序实例 class.
上调用该方法
这是执行此操作的代码...
def method_missing(method_name, *args)
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
您可以在此处检查代码...
https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb
鉴于我们在 application.rb 中设置了自定义 header 作为
config.action_mailer.default_options = {
'X-MyCustomHeader' => "Default_value" }
我希望能够从任何邮件程序中调用方法,例如 remove_custom_header
,并且它已删除 header,或者至少设置为 nil。
因为它是自定义 header(以 X- 开头)ActionMailer 将允许创建多个,而不是像使用标准 headers 那样重置它。
定义可以覆盖它的方法的最佳方法是什么?
我遇到的问题是你在邮件方法中调用 headers['X-MyCustomHeader'] = nil
它不会覆盖它,它只是创建第二个 header,其中条目为 nil,而原始的来自 application.rb 在电子邮件中。
我能找到的覆盖默认设置的唯一方法是在 ApplicationMailer(或任何继承邮件程序 class')中调用 default 'X-MyCustomHeader' => nil
,如下所示,但不是在方法中.
class ApplicatioMailer < ActionMailer::Base
helper :application
default 'X-MyCustomHeader' => nil
end
但我想在方法的基础上调用它,而不是在邮件程序 class 本身中调用它,因为该应用程序有很多邮件程序 classes 并且我希望将其禁用一两个一些 Mailers 中的方法。
我目前的解决方案是:
class ApplicatioMailer < ActionMailer::Base
helper :application
default 'X-MyCustomHeader' => Proc.new { @is_disabled ? nil : Rails.config.action_mailer.default_header }
def remove_custom_header
@is_disabled = true
end
end
这似乎有效,因为您正在使用来自 ActionMailer 的 default
调用来覆盖。现在我已经对此进行了测试,它确实适用于多个调用,因此 @is_disabled
的值似乎不会在邮件程序调用之间持续存在。我不明白 class var 在这里是如何工作的,在调用它的邮件程序的超类中,当没有创建 class 的新 object 时,但它似乎每个新的都是空的调用 ApplicationMailer,所以对我来说它有效。然而,这是一个好的解决方案吗?我错过了一些明显的东西吗?在这种情况下使用 class var 我觉得不舒服,但我可以想出另一种方法!
在此先感谢您的帮助!
编辑::例如,我想像这样调用我的邮件程序..
class MyMailer < ApplicatioMailer
def mail_method_one(email)
# my call
remove_custom_header
mail from: a.format, subject: email.subject
end
end
而且如果我上面设置 class var 的方法是有效和健全的(我有点怀疑)有人可以解释为什么我会感兴趣它是如何工作的并且必须证明它对我的领导开发! :)
与其看起来的相反,@is_disabled
不是 class 变量,它是一个实例变量。正如你定义的方法被定义为一个实例class
请注意,您正在做...
def mail_method_one(email)
...不是...
def self.mail_method_one(email)
您可以通过使用 pry
gem 或其他检查工具停止执行来自行确认...
def mail_method_one(email)
binding.pry
如果你检查 self
你会发现你在邮件程序的一个实例中。
您确实将其称为 class 方法,但那是因为操作邮件程序使用 method_missing 来测试缺少的 class 方法是否实际上是一个实例方法并创建一个新实例MessageDelivery 传递 class 名称、方法名称和参数,随后在邮件程序实例 class.
上调用该方法这是执行此操作的代码...
def method_missing(method_name, *args)
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
您可以在此处检查代码... https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb