【问题标题】:How do I get request.host in rails mailer preview?如何在 Rails 邮件预览中获取 request.host?
【发布时间】:2018-06-14 21:52:10
【问题描述】:

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

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

Rails 似乎正在使用这个控制器来设置所有这些魔法:

Rails::MailersController#preview

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

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

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

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

【问题讨论】:

    标签: ruby-on-rails actionmailer preview


    【解决方案1】:

    request 在模型和邮件中不可用。使您能够在modelmailer 中访问request 的唯一方法是从controller 传递request。检查以下示例:

    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

    【讨论】:

    • 如果我可以访问控制器,这个答案将是一个简单的答案。我不确定你是否完全理解这个问题。请查阅有关邮件预览的文档:guides.rubyonrails.org/… 控制器内置于 Rails 中,我唯一能想到的可能就是以某种方式覆盖它。
    【解决方案2】:

    在 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

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      相关资源
      最近更新 更多