当我以前使用MailView
gem来预览ActionMailer
个电子邮件时,我会访问@rack_env
以在不同条件下预览我的电子邮件,例如交付给特定用户或特定区域,或具有特定输入。使用新的(ish)ActionMailer::Preview
,实例变量未被设置,params
不存在。有谁知道如何使用/rails/mailers/:mailer/:action
访问GET参数ActionMailer::Preview
?
理想情况下,我希望能够请求/rails/mailers/my_mailer/mymail?user_id=123
并像
class MyMailerPreview < ActionMailer::Preview
def mymail
MyMailer.mymail(User.find(params[:user_id]))
end
end
答案 0 :(得分:0)
ActionMailer无权访问控制器参数,因此请将所需的参数作为参数传递:
class MyMailerPreview < ActionMailer::Preview
def mymail(user_id)
MyMailer.mymail(User.find(user_id))
end
end
然后在你的控制器中:
MyMailerPreview.mymail(params[:user_id]).deliver
答案 1 :(得分:0)
我想出了一个简单的解决方案,并用blog post on extending ActionMailer详细说明。这是我发现的最简单的解决方案,我唯一关心的是它如何影响其他控制器的性能。
# config/initializers/mailer_injection.rb
# This allows `request` to be accessed from ActionMailer Previews
# And @request to be accessed from rendered view templates
# Easy to inject any other variables like current_user here as well
module MailerInjection
def inject(hash)
hash.keys.each do |key|
define_method key.to_sym do
eval " @#{key} = hash[key] "
end
end
end
end
class ActionMailer::Preview
extend MailerInjection
end
class ActionMailer::Base
extend MailerInjection
end
class ActionController::Base
before_filter :inject_request
def inject_request
ActionMailer::Preview.inject({ request: request })
ActionMailer::Base.inject({ request: request })
end
end
答案 2 :(得分:0)
这是我用于特定参数的解决方案(在我的情况下加载特定订单),您可以修改它以使其更通用并适用于任何或所有参数
它在XXXMailerPreview类中使用了一个类变量,如果你在dev中运行它应该不是问题。这是必需的,因为至少在Rails 5中,预览显示在IFrame中,并且添加到预览URL的url参数不会传递到IFrame网址。
具体来说,此示例代码适用于Spree中的Abandoned Cart电子邮件,但它也可用于任何订单特定的电子邮件预览
预览http://localhost:3000/rails/mailers/abandonded_checkout_mailer
上的所有电子邮件在mailer_controller_decorator.rb
中,你可以在加载Rails之后加载任何你想要的东西
module MailerPreviewOrderNumber
def set_order_number(order_number)
@order_number = order_number
end
def get_order_number
@order_number
end
def order_for_preview
order_number = get_order_number
order = Spree::Order.find_by(:number => order_number) if order_number.present?
order = yield if order.blank?
order
end
end
Rails::MailersController.class_eval do
before_action :save_order_number, only: [:preview]
def save_order_number
if @preview.present? && @preview.respond_to?(:set_order_number)
@preview.set_order_number(params[:order]) if params[:order].present?
end
end
end
在您的XXXMailerPreview文件中
class AbandondedCheckoutMailerPreview < ActionMailer::Preview
extend MailerPreviewOrderNumber
def abandoned_checkout_email
if Rails.env.development?
order = self.class.order_for_preview do
Spree::Order.order(updated_at: :desc).last
end
AbandonedCheckoutMailer.abandoned_checkout_email(order)
end
end
end
传递给order_for_preview
的块用于第一次没有为预览URL提供订单参数的情况