如何在ActionMailer预览中使用设置方法?

3
我希望避免为多个邮件预览重复设置。 清理它的最佳方法是什么?
class MyMailerPreview < ActionMailer::Preview
  def email1
    setup
    mailer.email1
  end

  def email2
    setup
    mailer.email2
  end

  def email3
    setup
    mailer.email3
  end
end

也许你可以在“initialize”方法中调用它。 - dev-cc
@Tom 我更新了我的答案,提供了几个可以与你的预览一起使用的解决方案。 - trueinViso
4个回答

4

我找到了两种可能的解决方案:

有一个叫做 preview_interceptors 的东西,用于在生成邮件预览时使用,你可以像这样添加自己的拦截器:

config/environments/development.rb

config.action_mailer.preview_interceptors = :my_setup

test/mailers/previews/my_setup.rb

class MySetup                                                                                         
  def self.previewing_email(message)                                                                   
    message.subject = "New subject"                                                                                             
  end                                                                                                  
end  

test/mailers/previews/user_mailer_preview.rb

class UserMailerPreview < ActionMailer::Preview 
  include ActionMailer::Previews
  register_preview_interceptor :my_setup

  def welcome_email                                                                                    
    UserMailer.with(user: User.first).welcome_email                                                    
  end                                                                                                                                                                                                                                                                                                         
end          

message参数是ActionMailer::Parameterized::MessageDelivery的一个实例,我不确定你可以对它做什么,但你可以在邮件本身上设置一些属性。

关于预览拦截器的文档很少,但在这里有一个链接,展示了Rails如何使用它们。

  # Previews can also be intercepted in a similar manner as deliveries can be by registering
  # a preview interceptor that has a <tt>previewing_email</tt> method:
  #
  #   class CssInlineStyler
  #     def self.previewing_email(message)
  #       # inline CSS styles
  #     end
  #   end
  #
  #   config.action_mailer.preview_interceptors :css_inline_styler
  #
  # Note that interceptors need to be registered both with <tt>register_interceptor</tt>
  # and <tt>register_preview_interceptor</tt> if they should operate on both sending and
  # previewing emails.

我试图在类中包含Rails的before_action,但它无法钩住预览器中的方法,所以我发现的第二个选择是像这样构建自己的before_action

module MySetup                                                                                      
  def before_action(*names)                                                                         
    UserMailer.instance_methods(false).each do |method|                                             
      alias_method "old_#{method}", method                                                          

      define_method method do                                                                       
        names.each do |name|                                                                        
          send(name)                                                                                
        end                                                                                         

        send("old_#{method}")                                                                       
      end                                                                                           
    end                                                                                             
  end                                                                                               
end    

class UserMailerPreview < ActionMailer::Preview 
  extend MySetup

  def welcome_email                                                                                 
    UserMailer.with(user: User.first).welcome_email                                                 
  end 

  before_action :setup

  private

  def setup
    puts "Setting up"
  end
end

1
我在询问邮件预览,而不是邮件本身。 - Tom Rossi
我担心拦截器直到邮件实际呈现后才运行? - Tom Rossi
不知道您具体想要做什么,所以很难确定它有多有用,但它确实会在在浏览器中呈现之前调用“previewing_email”方法。您可以在电子邮件本身呈现在浏览器之前修改不同的属性。例如,我能够更改电子邮件的主题,并在浏览器中看到我的修改后的主题。如果这还不够,那么我想您可能需要创建自己的“before_action”,或者继续使用您目前正在使用的方式。 - trueinViso
除非你能够弄清楚如何在预览器中使用Rails内置的before_action,如果你成功了,我会很感激你分享一下你是怎么做到的:D - trueinViso
我们并不确定,实际上我们甚至不在应用程序中使用 rails 邮件封装。我们目前正在使用 litmus.com 来构建电子邮件。我可能会使用服务对象来实例化我的对象,并将它们传递给邮件发送器,并完成这个过程。 - trueinViso
显示剩余2条评论

2

使用initialize方法。

只需重写父类的initialize方法,调用super,然后运行设置:

class MyMailerPreview < ActionMailer::Preview

  def initialize( params = {} )
    super( params )

    @email_address = "jules@verne.com"
  end

  def email1
    mailer.email1( @email_address )
  end

end

你可以将ActionMailer::Preview.new方法在这里作为参考。


0
你可以扩展Rails::MailersController
# config/initializers/mailer_preview_setup.rb

class Rails::MailersController
  before_action :setup, only: [:preview, :download]

  private

  def setup
    # your code here
  end
end

或者 prepend 来覆盖

# config/initializers/mailer_preview_setup.rb
module MailerPreviewSetup
  def preview
    setup
    super
  end

  private

  def setup
    # your code here
  end
end

Rails.configuration.to_prepare do
  Rails::MailersController.prepend MailerPreviewSetup
end


0

根据我的理解,也许你可以将它添加到一个单一的方法中,该方法以邮件发送方法作为参数。

class MyMailerPreview < ActionMailer::Preview
  def email_for(emailx) # (Pass the method(email1, etc) as an argument where you're calling it
    setup
    mailer.send(emailx.to_sym) # Call the method param as a method on the mailer
  end
end

这对您来说可以吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接