ruby-on-railsrubyruby-on-rails-4mail-form

Passing dynamic subject to Rails mail_form


I am using gem mail_form to handle contact in a Rails app, and I have 6 different contact forms.

I put a hidden_field_tag in the form and pass the desired subject as a variable. In the html, the value is there but the email arrives with (no subject). What can I be doing wrong?

In controllers

def where_to_buy
   @contact = Contact.new
   @the_subject = "Where to buy"
end

In contact form

= form_for @contact do |f|
  = render "form", f: f
  = f.text_area :message
  .hide
    = f.text_field :nickname, hint: 'Leave this field empty!'
    = hidden_field_tag    :mail_subject, @the_subject
  = f.submit "Send Message"

In model

class Contact < MailForm::Base
  attribute :mail_subject
  attribute :first_name, validate: true
  attribute :last_name,  validate: true
  attribute :message,    validate: true
  attribute :nickname,   captcha:  true

  def headers
    {
      subject: %(#{mail_subject}),
      to:      "jorge@email123.com",
      from:    %("#{first_name} #{last_name}" <#{email}>)
    }
  end
end

Output html in chrome:

<input type="hidden" name="mail_subject" id="mail_subject" value="Where to buy">

Solution

  • Instead of:

    = hidden_field_tag :mail_subject, @the_subject
    

    You will want to use:

    = f.hidden_field :mail_subject, value: @the_subject
    

    If you inspect the parameters that are logged into your development.log you will see why.

    When you use hidden_field_tag the mail_subject is defined as its own independent parameter and will not be included in the contact hash. You'll have something like:

    params = { "contact" => { "message" => "text here", ... }, "mail_subject => "Where to buy" }
    

    But when you use f.hidden_field the mail_subject will be included in the contact hash. You'll have something like:

    params = { "contact" => { "message" => "text here", "mail_subject => "Where to buy", ... } }
    

    And then when you call Contact.new(params[:contact]) the new contact object will get the mail_subject value.