1

While sending a mail, I need to convert the mail as a pdf document.

In order to do this i need to bind the erb template with the data, but the erb template contains instance variables

let the template be..,

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

I have followed this solution mention in the question, Using a namespace for binding the templates with data.

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)

This works fine for the templates which doesn't contains instance variables.

I need to pass data to the instance variables in the template is there any possibility for doing this.

And I knew a way to solve this problem by assigning the instance variables with the data that we bind ie)

in the template

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

But I don't want this kind of implementation.

Community
  • 1
  • 1
Bala Karthik
  • 1,353
  • 2
  • 17
  • 26

2 Answers2

3

I hope you are rendering the HTML string to generate some PDF / kind of files. In those case, we need to declare the instance variable from where your are invoking those calls. So that it can be accessed through out the request. (Same mailer concepts)

I tried the below one for those cases. It works.

  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
Jayaprakash
  • 1,407
  • 1
  • 9
  • 19
2

You can modify your Namespace#initialize method so that it assigns instance variables instead of defining instance methods for each key of your hash:

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>"
omnikron
  • 2,211
  • 17
  • 30