Contact Form Mailer in Rails 4

11,396

It turned out that I hadn't configured my Heroku app with an external SMTP service (since I have never done anything with email before, I didn't know to do this). Since I'm relatively familiar with MailChimp, and especially since their Mandrill service has a free tier (I am building this app for a student organization), I easily added Mandrill to my Heroku app and included the following settings in application.rb:

ActionMailer::Base.smtp_settings = {
    address: 'smtp.mandrillapp.com',
    port: 587,
    user_name: ENV['MANDRILL_USERNAME'],
    password: ENV['MANDRILL_APIKEY']
}

Where the ENV vars were set automatically by the add-on.

Share:
11,396

Related videos on Youtube

sethfri
Author by

sethfri

Questions I ask on here don't represent work being done by my employer. I code a lot in my spare time too.

Updated on June 04, 2022

Comments

  • sethfri
    sethfri almost 2 years

    I am trying to build a contact form in Rails 4, where the form takes a name, email, and body and sends it to my email address. Upon clicking "Submit", the app redirects back to the Contact page correctly, but no email appears to get sent.

    routes.rb

    match '/send_mail', to: 'contact#send_mail', via: 'post'
    

    contact_email.html.erb

    <!DOCTYPE html>
    <html>
        <head>
            <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
            <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
        </head>
        <body>
            <p>You have received the following email from <%= "#{ @name } (#{ @email }):" %></p>
            <p><%= @body %></p>
        </body>
    </html>
    

    contact_controller.rb

    def send_mail
        name = params[:name]
        email = params[:email]
        body = params[:comments]
        ContactMailer.contact_email(name, email, body).deliver
        redirect_to contact_path, notice: 'Message sent'
    end
    

    contact_mailer.rb

    class ContactMailer < ActionMailer::Base
        default to: # my email address
    
        def contact_email(name, email, body)
            @name = name
            @email = email
            @body = body`enter code here`
    
            mail(from: email, subject: 'Contact Request')
        end
    end
    

    contact.html.erb

    <div class="container-content">
        <div class="container">
            <%= form_tag(send_mail_path) do %>
                <div class="form-group">
                    <%= label_tag 'name', 'Name' %>
                    <%= text_field_tag 'name', nil, class: 'form-control', placeholder: 'Your Name' %>
                </div>
               <div class="form-group">
                   <%= label_tag 'email', 'Email' %>
                   <%= email_field_tag 'email', nil, class: 'form-control', placeholder: 'Your Email Address' %>
               </div>
               <div class="form-group">
                   <%= label_tag 'comments', 'Comments' %>
                   <%= text_area_tag 'comments', nil, class: 'form-control', rows: 4, placeholder: 'Comments...' %>
               </div>
               <%= submit_tag nil, class: 'btn btn-default btn-about pull-right' %>
           <% end %>
      </div>
    </div>
    

    application.rb

    config.action_mailer.delivery_method = :sendmail
    config.action_mailer.perform_deliveries = true
    config.action_mailer.raise_delivery_errors = true
    
    • jb_314
      jb_314 over 10 years
      Are you running in development mode with delivery_method set to :test? Do you see your e-mail in your log?
    • Danny
      Danny over 10 years
      Maybe a stupid question: did you change config.action_mailer.perform_deliveries = true, as by default this is on false, preventing mails to be sent from the development environment...
    • sethfri
      sethfri over 10 years
      @np_ No message is sent regardless of whether I'm running in production or via localhost
    • sethfri
      sethfri over 10 years
      @Danny Van Hoof I did set that to true, but no email is getting sent whether I'm in development or production.
    • Danny
      Danny over 10 years
      Your code looks ok. So, my guess is it has to do something with your smtp settings... Has it ever worked? In other words, are you sure your smtp settings are OK?
    • Richard Peck
      Richard Peck over 10 years
      What params are you getting from the form submit? You sure they're just going to be params[:name] etc?
    • Bart
      Bart over 10 years
      Can you try sending email from console and look for errors?
    • jb_314
      jb_314 over 10 years
      @sethfri: with delivery_method set to :test, then e-mails will be put in the log file. You can use that to ensure that your mailer is working (in that it's getting called and generating a message), and therefore isolating the problem to your SMTP settings.
    • sethfri
      sethfri over 10 years
      @DannyVanHoof No, this is the first time I am trying anything with mailers, so it has not worked in the past. I've updated the question with my application.rb settings.
    • sethfri
      sethfri over 10 years
      @BartoszKopiński When I try sending the email from the console Sent mail to <My Email Address> (39.6ms) appears, which makes me think it's working. No errors in sight, but no email showing up either.
    • sethfri
      sethfri over 10 years
      @RichPeck Yes, these are the correct parameters.
  • smatthewenglish
    smatthewenglish over 7 years
    do you need those ENV texts? can't you just 'put it in quotes'?
  • sethfri
    sethfri over 7 years
    Do you mean instead of retrieving an ENV var, using the username and password as raw strings? That would be functional, but it's not a good practice. Setting it in the ENV is better for security because it's not readily available to anyone with access to the source code. Additionally, if you need to modify these values ever, you can do so without redeploying your whole app. You just modify the ENV and reboot the app.