通过在发送电子邮件时绑定包含实例变量的 erb 模板生成 PDF

Generate PDF by binding erb template that contains instance variable while sending email

发送邮件时,我需要将邮件转换为pdf文档。

为此,我需要将 erb 模板与数据绑定,但 erb 模板包含实例变量

让模板成为..,

<h1>Name: <%=@name%><h1>
<h2>Address: <%= @address %><h2>

我遵循了 question 中提到的解决方案,使用命名空间将模板与数据绑定。

class Namespace
  def initialize(hash)
    hash.each do |key, value|
      singleton_class.send(:define_method, key) { value }
    end 
  end

  def get_binding
    binding
  end
end

ns = Namespace.new(name: 'Joan', address: 'Chennai, India')
ERB.new(template).result(ns.get_binding)

这适用于不包含实例变量的模板。

我需要将数据传递给模板中的实例变量,是否有可能这样做。

而且我知道一种解决这个问题的方法,方法是将实例变量分配给我们绑定的数据,即)

在模板中

   <% @name = name %> 
   <% @address = address %>
   <h1>Name: <%=@name%><h1>
   <h2>Address: <%= @address %><h2>

但我想要这种实现方式。

我希望您正在渲染 HTML 字符串以生成一些 PDF 文件。在那些情况下,我们需要从您调用这些调用的地方声明实例变量。这样就可以通过请求访问它。 (相同的邮件程序概念)

对于这些情况,我尝试了以下方法。有效。

  def generate_attachment(your_variable)
    @your_instance_variable = your_variable

    attachments['attachment.pdf'] = WickedPdf.new.pdf_from_string(render_to_string(:pdf => "filename.pdf",:template => '/_template.html.erb'))
  end

您可以修改 Namespace#initialize 方法,使其分配实例变量,而不是为散列的每个键定义实例方法:

class Namespace
  def initialize(hash)
    hash.each do |key, value|
      instance_variable_set(:"@#{key}", value)
    end 
  end

  def get_binding
    binding
  end
end 

ns = Namespace.new(name: 'Joan', address: 'Chennai, India')
#=> #<Namespace:0x007feca2400e98 @address="Chennai, India", @name="Joan">
ERB.new(template).result(ns.get_binding)
#=> "<h1>Name: Joan<h1>\n<h2>Address: Chennai, India<h2>"