[英]access request parameters in Rails 4.1 mailer preview
當我以前使用MailView
gem預覽ActionMailer
電子郵件時,我將訪問@rack_env
以在不同條件下預覽我的電子郵件,例如,傳遞給特定用戶或特定區域設置或具有特定輸入。 使用新的(ish) ActionMailer::Preview
,不會設置實例變量,並且params
不存在。 有誰知道如何使用ActionMailer::Preview
訪問GET參數到/rails/mailers/:mailer/:action
?
理想情況下,我希望能夠請求/rails/mailers/my_mailer/mymail?user_id=123
並像
class MyMailerPreview < ActionMailer::Preview
def mymail
MyMailer.mymail(User.find(params[:user_id]))
end
end
ActionMailer無法訪問控制器參數,因此請將您需要的參數作為參數傳遞:
class MyMailerPreview < ActionMailer::Preview
def mymail(user_id)
MyMailer.mymail(User.find(user_id))
end
end
然后在您的控制器中:
MyMailerPreview.mymail(params[:user_id]).deliver
我提出了一個簡單的解決方案,並在有關擴展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
這是我用於特定參數的解決方案(以加載特定訂單為例),您可以對其進行修改以使其更通用並適用於任何或所有參數
它在XXXMailerPreview類中使用一個類變量,如果您在dev中運行,則應該沒有問題。 這是必需的,因為至少在Rails 5中,預覽是在IFrame中顯示的,並且添加到預覽URL中的URL參數不會傳遞到IFrame URL。
具體來說,此示例代碼用於Spree中的“廢棄購物車”電子郵件,但也用於任何特定於訂單的電子郵件預覽
在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
如果第一次沒有向預覽URL提供訂單參數,則使用傳遞給order_for_preview
的代碼塊
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.