在 ActionMailer 预览中使用 Struct

Using Struct in ActionMailer preview

我正在使用 ActionMailer Preview 测试我的一个邮件程序并使用 Struct 创建我的对象

class TransactionMailerPreview < ActionMailer::Preview
  include Roadie::Rails::Automatic

  def transaction_complete_mailer
    orders = Struct.new(:image, :image_size, :mount, :frame, :frame_color)
    transaction = Struct.new(:first_name, :email)
    @transaction = transaction.new('Richard Lewis', 'test@gmail.com')
    @orders = orders.new("Test Print Name", "10x8 Image Size", "10x8 Mount Size", "10x8 Frame Size", "White Frame")
    TransactionMailer.transaction_complete_mailer(@transaction, @orders) 
  end
end

这是我的真实邮件class

class TransactionMailer < ApplicationMailer
  default from: ENV['EMAIL_ADDRESS']

  def transaction_complete_mailer(transaction, orders)
    @transaction = transaction
    @orders = orders
    attachments.inline['photography-logo-text.png'] = File.read(Rails.root.join('app', 'assets', 'images', 'photography-logo-text.png'))
    mail(to: @transaction.email, subject: 'Your order from Glenn GB Photography') do |format|
      format.html { render file: 'transaction_mailer/transaction_message.html.erb', layout: 'mailer' }
    end
  end
end

在我看来,我遍历了 @orders,因为可能有多个

transaction_message.htmnl.erb

<% @orders.each do |order| %>
  <div class="order-summary">
    <p><span class="bold">Print:</span><%= order.image %></p>
    <p><span class="bold">Print Size:</span><%= order.image_size %></p>
    <p><span class="bold">Mount:</span><%= order.mount %></p>
    <p><span class="bold">Frame:</span><%= order.frame %></p>
    <p><span class="bold">Frame Color:</span><%= order.frame_color %></p>
  </div>
<% end %>

当我在预览中操作此邮件程序时出现错误

undefined method `image' for "Test Print Name":String

我这里有两个问题

  1. 为什么我会收到错误消息?

  2. 如何创建多个订单对象?

@ordersstruct 类型的单一对象,但您的 transaction_complete_mailer 需要一个名为 @orders 的 array/collection。因此,当您在 Mailer 中调用 @orders.each do |order| 时,它实际上是在遍历 @orders 结构对象中的每个 key/value。这解释了您收到的错误,因为 "Test Print Name" 是您在 Struct.

中声明的第一个密钥

将结构包装在数组中应该可以解决问题:

class TransactionMailerPreview < ActionMailer::Preview
  include Roadie::Rails::Automatic

  def transaction_complete_mailer
    orders = Struct.new(:image, :image_size, :mount, :frame, :frame_color)
    transaction = Struct.new(:first_name, :email)
    @transaction = transaction.new('Richard Lewis', 'test@gmail.com')
    @order = orders.new("Test Print Name", "10x8 Image Size", "10x8 Mount Size", "10x8 Frame Size", "White Frame") # Renamed to @order, since this is a single object
    TransactionMailer.transaction_complete_mailer([@transaction], [@order]) 
  end
end