【问题标题】:How to attach dynamic file content in email如何在电子邮件中附加动态文件内容
【发布时间】:2016-05-23 23:23:40
【问题描述】:

我想在我的电子邮件中附加一个动态文件。我有以下代码:

attachments["#{@company}likelist.xls"] = File.read("#{Rails.root}/app/views/products/like_list.xls.erb")

like_list.xls.erb 是通过在 Ruby 中迭代变量创建的动态 HTML 表。我使用respond_to format.xlslike_list.html.erb 表转换为XLS,但是,发送的附件是空的,因为没有执行任何Ruby 代码。 File.read 只读取静态文件。

like_list.xls.erb 看起来像这样:

<table border="1">
  <thead>
  <tr>
    <th><%= t ('product_table.name')%></th>
    <th><%= t ('product_table.code')%></th>
  </tr>
  </thead>
  <tbody>
    <% @like_list.each do |key, value| %>
      <% value.each do |t| %>
        <tr>
          <td><%=t.code%></td>
          <td><%=key%></td>
...

有什么方法可以在 Rails 4 中附加动态文件?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    我认为那是因为您只发送了一个模板。但是你应该先建一个表。

    我不知道你的@like_list 是什么数据类型,但假设它是一个哈希。

    在这种情况下,您应该构建您的附件。这只是一个显示基本方法的示例:

      # mailer
      def table_deliver
        to = "user@example.com"
        from = "no-reply@example.com"
        subject = "Foo"
    
        @company = "Ggl"
        @like_list = { foo: 1,
                       bar: 2,
                       baz: 3 }
        attachments["#{@company}likelist.xls"] = build_table(@like_list)
        @body = "Mail body"
        mail(to: to, from: from, subject: subject)
      end
    
      private
    
      def build_table(data)
        opts = OpenStruct.new(data)
        template = ERB.new(File.read("#{Rails.root}/app/views/products/like_list.xls.erb"))
        template.result(opts.instance_eval { binding })
      end
    
    # template
    
    <table>
      <thead>
        <th>foo</th>
        <th>bar</th>
      </thead>
      <tbody>
        <% data.each do |k, v| %>
          <tr>
            <td><%= k %></td>
            <td><%= v %></td>
          </tr>
        <% end %>
      </tbody>
    </table>
    

    以及在 letter_opener 中的结果:

    在 libre office 中打开的附件

    希望对您有所帮助,并随时提出其他问题。

    更新

    首先你从你的哈希参数创建一个OpenStruct。然后创建一个新的 ERB 类实例。

    result 是 ERB 类的方法,将参数应用于现有模板。

    binding 是一个对象,它提供对另一个对象拥有的实例方法和变量的访问。

    更多信息here

    instance_eval 是一个 Object 方法,它在接收者 (obj) 的上下文中评估包含 Ruby 源代码或给定块的字符串。

    更多信息here

    因此,该代码执行以下操作

    • 使用键值对创建一些结构
    • 创建新模板
    • 在模板上下文中执行binding 对象并将键值对分配给模板。

    您可以参考这个SO post了解更多详情

    【讨论】:

    • 感谢您的帮助。你能解释一下template.result(opts.instance_eval { binding }) 的作用吗?
    猜你喜欢
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多