如何在rails mailer preview中获取request.host?

时间:2018-06-14 21:52:11

标签: ruby-on-rails actionmailer preview

很棒:rails现在提供了一种使用继承自

的类来预览邮件程序视图的方法
 ActionMailer::Preview

Rails似乎正在使用这个控制器来设置这一切:

Rails::MailersController#preview

不幸的是,我的应用程序是多租户的,我的邮件程序依赖于request.host传递给它们,以便根据它们被触发的域进行样式设置。

我希望能够在设置邮件预览时关闭地址栏中的网址。我必须做一些奇怪的事情才能使这个工作(部分原因是因为我也在为这些创建功能规范),但主要是因为我必须在无法访问请求对象的上下文中设置我的邮件程序,甚至虽然我的邮寄者需要它才能正常工作。

class SiteMailerPreview < ActionMailer::Preview
  def support_email_notification
    support_email = SupportEmail.first
    SiteMailer.support_email_notification(support_email, request).deliver
  end

  private

  def request
    request = Struct.new(:host).new
    request.host = 'local.myhost.net'
    request
  end
end

目前主机是静态设置的,所以我无法真正针对多个主机测试邮件程序。

2 个答案:

答案 0 :(得分:0)

request将不适用于型号和邮寄广告。允许您在requestmodel中访问mailer的唯一方法是从request传递controller。请查看以下示例:

class BooksController < ApplicationController
  def create
    book = Book.create(title: 'xyz', author: current_user)
    BookMailer.new_book_added(book.id, request).deliver
  end
end

邮件可能如下所示:

class BookMailer < ActionMailer::Base
     def new_book_added(book_id, request)
        @book = Book.find book_id
        @url  = books_url(@book, host: request.host_with_port )
        mail(:to => @book.author.email,
             :subject => "Your book is published")
     end
end

并且由于您提到您的应用是multitenant并且假设您正在使用apartment gem,您可以使用Apartment::Tenant.current来提供subdomain

答案 1 :(得分:0)

在Rails 5.2中,您可以从文档中获得ActiveSupport :: CurrentAttributes:

抽象超类,提供线程隔离的属性单例,该单例在每个请求之前和之后自动重置。这样,您就可以使整个系统轻松使用所有按请求的属性。

我目前在我的应用程序中使用它来存储我在任何地方都需要的特定要求的东西(甚至模型,邮件程序,装饰器等)。它非常有用。如果正确设置ActiveSupport :: CurrentAttributes,则可以执行以下操作:

Current.request

这是我在应用程序中设置的内容:

在我的模型中

#models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :request_id, :user_agent, :ip_address, :user, :request
end

控制器问题:

#controllers/set_current_request_details.rb
module SetCurrentRequestDetails
  extend ActiveSupport::Concern

  included do
    before_action do
      Current.request_id = request.uuid
      Current.user_agent = request.user_agent
      Current.ip_address = request.ip
      Current.request = request
    end
  end
end

控制器:

#controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include SetCurrentRequestDetails

...

来源:https://api.rubyonrails.org/v5.2/classes/ActiveSupport/CurrentAttributes.html