Rails before_action 对于将使用邮件程序参数的 ActionMailer
Rails before_action for ActionMailer that would use mailer arguments
假设我有一个发送不同电子邮件的邮件程序,但预计会使用相同的参数调用。我想为所有邮件操作处理这些参数。因此,调用 before_action
将读取发送到邮件程序方法的参数
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
before_filter do |c|
# c.prepare_mail # Will fail, because I need to pass `same_param` arguments
# # I want to send the original arguments
# c.prepare_mail(same_param) # How do I get `same_param` here ?
end
def action1(same_param)
# email view is going to use @to, @from, @context
method_only_specific_to_action1
end
def action2(same_param)
# email view is going to use @to, @from, @context
method_only_specific_to_action2
end
private
def prepare_mail(same_params)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
end
end
然后在我的 controller/service 我在某处做
MyMailer.actionx(*mailer_params).deliver_now
如何访问 before_action
块中的 same_param
参数列表?
编辑:
我想重构
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
def action1(same_param)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
method_only_specific_to_action1
end
def action2(same_param)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
method_only_specific_to_action2
end
def actionx
...
end
end
以及这次重构
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
def action1(same_param)
prepare_mail(same_params)
method_only_specific_to_action1
end
def action2(same_param)
prepare_mail(same_params)
method_only_specific_to_action2
end
def actionx
...
end
private
def prepare_mail(same_params)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
end
end
感觉不理想(prepare_mail(same_params)
在每个动作中重复)
因此上面的建议
Solution1:
如果你不关心格式,我建议你使用这个
MyMailer.generic("actionx", *mailer_params).deliver_now
def generic(actiontype, *mailer_params)
# custom logic goes here to construct the to, from, etc.,
# new_options from custom logic
self.send(actiontype, new_options)
end
alternative solution below using method_missing from the parent controller
将你的逻辑放在那里是不对的,但如果你仍然想这样做,你可以使用 method_missing 将你的逻辑放在那里并跳过 action1 和 action2 方法。
来自action_mailer的method_missing原创,可作为参考:
def method_missing(method_name, *args)
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
根据 Sairam 的回答,我想到了以下但感觉有点奇怪,难道不能用 before_action
回调来完成吗??
class MyMailer < ApplicationMailer
# Simulation of before_action callback that would support passing the *args to the callback method
def self.method_missing(method_name, *args)
method_name = :"#{method_name.to_s}_headers_prefilled"
if action_methods.include?(method_name)
mailer = MyMailer.generic(*args) # The before_action callback that passes *args
mailer.send(method_name, *args) # The action itself
else
super
end
end
def generic(*mailer_params)
# custom logic goes here to construct the headers to, from, etc.,
end
def action1_headers_prefilled(mailer_params)
# Logic only relevant for action1
end
我还丢失了 before_action 中所有很酷的东西(传递 only
或 except
数组等)
ActionMailer 使用 AbstractController::Callbacks
模块。我试过了,它似乎对我有用。
代码
class MyMailer < ApplicationMailer
def process_action(*args)
# process the args here
puts args
super
end
def some_mail(*args)
end
end
MyMailer.some_mail(1, 2) #=> prints ['some_mail', 1, 2]
更新
如果您使用的是 Rails 5.1,您可以查看 ActionMailer::Parameterized
假设我有一个发送不同电子邮件的邮件程序,但预计会使用相同的参数调用。我想为所有邮件操作处理这些参数。因此,调用 before_action
将读取发送到邮件程序方法的参数
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
before_filter do |c|
# c.prepare_mail # Will fail, because I need to pass `same_param` arguments
# # I want to send the original arguments
# c.prepare_mail(same_param) # How do I get `same_param` here ?
end
def action1(same_param)
# email view is going to use @to, @from, @context
method_only_specific_to_action1
end
def action2(same_param)
# email view is going to use @to, @from, @context
method_only_specific_to_action2
end
private
def prepare_mail(same_params)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
end
end
然后在我的 controller/service 我在某处做
MyMailer.actionx(*mailer_params).deliver_now
如何访问 before_action
块中的 same_param
参数列表?
编辑:
我想重构
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
def action1(same_param)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
method_only_specific_to_action1
end
def action2(same_param)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
method_only_specific_to_action2
end
def actionx
...
end
end
以及这次重构
/mailers/my_mailer.rb
class MyMailer < ApplicationMailer
def action1(same_param)
prepare_mail(same_params)
method_only_specific_to_action1
end
def action2(same_param)
prepare_mail(same_params)
method_only_specific_to_action2
end
def actionx
...
end
private
def prepare_mail(same_params)
@to = same_params.recipient
@from = same_params.initiator
@context = same_params.context
end
end
感觉不理想(prepare_mail(same_params)
在每个动作中重复)
因此上面的建议
Solution1:
如果你不关心格式,我建议你使用这个
MyMailer.generic("actionx", *mailer_params).deliver_now
def generic(actiontype, *mailer_params)
# custom logic goes here to construct the to, from, etc.,
# new_options from custom logic
self.send(actiontype, new_options)
end
alternative solution below using method_missing from the parent controller
将你的逻辑放在那里是不对的,但如果你仍然想这样做,你可以使用 method_missing 将你的逻辑放在那里并跳过 action1 和 action2 方法。
来自action_mailer的method_missing原创,可作为参考:
def method_missing(method_name, *args)
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
根据 Sairam 的回答,我想到了以下但感觉有点奇怪,难道不能用 before_action
回调来完成吗??
class MyMailer < ApplicationMailer
# Simulation of before_action callback that would support passing the *args to the callback method
def self.method_missing(method_name, *args)
method_name = :"#{method_name.to_s}_headers_prefilled"
if action_methods.include?(method_name)
mailer = MyMailer.generic(*args) # The before_action callback that passes *args
mailer.send(method_name, *args) # The action itself
else
super
end
end
def generic(*mailer_params)
# custom logic goes here to construct the headers to, from, etc.,
end
def action1_headers_prefilled(mailer_params)
# Logic only relevant for action1
end
我还丢失了 before_action 中所有很酷的东西(传递 only
或 except
数组等)
ActionMailer 使用 AbstractController::Callbacks
模块。我试过了,它似乎对我有用。
代码
class MyMailer < ApplicationMailer
def process_action(*args)
# process the args here
puts args
super
end
def some_mail(*args)
end
end
MyMailer.some_mail(1, 2) #=> prints ['some_mail', 1, 2]
更新
如果您使用的是 Rails 5.1,您可以查看 ActionMailer::Parameterized