Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Action Mailer: How do I render dynamic data in an email body that is stored in the database?

I have Action Mailer setup to render an email using the body attribute of my Email model (in the database). I want to be able to use erb in the body but I can't figure out how to get it to render in the sent email message.

I'm able to get the body as a string with this code

# models/user_mailer.rb
def custom_email(user, email_id)
  email = Email.find(email_id)

  recipients    user.email
  from          "Mail It Example <[email protected]>"
  subject       "Hello From Mail It"
  sent_on       Time.now

  # pulls the email body and passes a string to the template views/user_mailer/customer_email.text.html.erb
  body          :msg => email.body
end

I came across this article http://rails-nutshell.labs.oreilly.com/ch05.html which says I can use render but I'm only able to get render :text to work and not render :inline

# models/user_mailer.rb
def custom_email(user, email_id)
  email = Email.find(email_id)

  recipients    user.email
  from          "Mail It Example <[email protected]>"
  subject       "Hello From Mail It"
  sent_on       Time.now

  # body          :msg => email.body
  body          :msg => (render :text => "Thanks for your order")  # renders text and passes as a variable to the template
  # body          :msg => (render :inline => "We shipped <%= Time.now %>")  # throws a NoMethodError

end

Update: Someone recommended using initialize_template_class on this thread http://www.ruby-forum.com/topic/67820. I now have this for body

body          :msg => initialize_template_class(:user => user).render(:inline => email.body)

It works but I don't understand this so I tried researching the private method and there is not much out there on it which makes me worry this is a hack and there is probably a better way. Suggestions?

like image 600
BeeZee Avatar asked Dec 09 '22 16:12

BeeZee


2 Answers

Even if you end up unable to use render :inline, you can always instantiate ERb yourself.

  require 'erb'

  x = 42
  template = ERB.new <<-EOF
    The value of x is: <%= x %>
  EOF
  puts template.result(binding)

  #binding here is Kernel::binding, the current variable binding, of which x is a part.
like image 104
Tim Snowhite Avatar answered Apr 27 '23 22:04

Tim Snowhite


In rails 3.2 :inline method of render works just fine.

  mail(:to => "[email protected]",
       :subject => "test") do |format|
    format.text { render :inline => text_erb_content }
    format.html { render :inline => html_erb_content }
  end
like image 30
trcarden Avatar answered Apr 27 '23 23:04

trcarden