簡體   English   中英

Rails 4.1郵件預覽中的訪問請求參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM