title: Add a contact form to Hartl's tutorial
body: <p>I'm learning Rails by following Hartl's tutorial and making my own adjustments to it. Now, I would like to extent it and add a contact form that sends an email message. Such is not included in the tutorial, but by the end of chapter 10 we're learned to use the mailer method and we've configured SendGrid on Heroku.</p>
  
  <p>I already have the view set up in the routes and think it would require the following additional steps:</p>
  
  <p>1) Terminal. rails generate mailer ContactForm</p>
  
  <p>2) In app/mailers/contactform.rb:</p>
  
  <pre><code>def send_contactform_email(visitor)
    @visitor = visitor
    mail( :to =&gt; myemail@example.com, :from =&gt; visitor.email, :subject =&gt; 'Contact form' )
  end
  </code></pre>
  
  <p>3) app/views/contactform_mailer/ (the view for the mail message) for example:</p>
  
  <pre><code>&lt;h1&gt;Website contact form&lt;/h1&gt;
  &lt;p&gt;On &lt;$= ... %&gt; &lt;%= "#{@visitor.name} (#{@visitor.email} sent the following message:" %&gt;&lt;/p&gt;
  &lt;p&gt;&lt;%= @visitor.message %&gt;&lt;/p&gt;
  </code></pre>
  
  <p>4) app\controllers\static_pages_controller <strong>(or another location?)</strong></p>
  
  <pre><code>  # Sends contact form email.
    def send_contact_form_email
      ContactFormMailer.send_contactform_email(visitor).deliver_now
      redirect_to contact_path, notice: 'Message sent'
    end
  </code></pre>
  
  <p>5) app\views\static_pages\contact.html.erb <strong>(I'm not sure about the first line, should I also do something in the routes.rb? My guess is this first line will have to tell to execute the method in step 4, which is not going to work the way it is now.)</strong></p>
  
  <pre><code>&lt;%= form_for(:static_pages, url: contactform_path) do |f| %&gt;
    &lt;i class="pt-row-icon glyphicon glyphicon-user"&gt;&lt;/i&gt; &lt;%= f.label :name %&gt;
    &lt;%= f.text_field :name, placeholder: 'Name', class: 'form-control' %&gt;
  
    &lt;i class="pt-row-icon glyphicon glyphicon-envelope"&gt;&lt;/i&gt; &lt;%= f.label :email %&gt;
    &lt;%= f.email_field :email, placeholder: 'Email', class: 'form-control' %&gt;
  
    &lt;i class="pt-row-icon glyphicon glyphicon-envelope"&gt;&lt;/i&gt; &lt;%= f.label :message %&gt;
    &lt;%= f.text_area :message, placeholder: 'Your message…', class: 'form-control' %&gt;
  
    &lt;%= f.submit "Send", class: "btn btn-primary" %&gt;
  &lt;% end %&gt;
  </code></pre>
  
  <p>I don't think this is 100% correct yet, particularly the bold sections. What are your thoughts?</p>
  
  <hr>
  
  <p><strong>UPDATE, VERSION 2:</strong> I've tried to make the updates as suggested by Ven and now have the code below. The idea as I understand it is that </p>
  
  <ul>
  <li>the controller in <code>def contact</code> sets the @message variable.</li>
  <li>the form_for knows it should fill this variable with params[:message].</li>
  <li>the controller adopts the values from the form_for and passes them to the mailer.</li>
  <li>the mailer uses the mailer view to design the message to be sent.</li>
  <li>the mailer sends it back to the controller that send the message.</li>
  </ul>
  
  <p>1) App/controllers/static_pages_controller.rb</p>
  
  <pre><code>class StaticPagesController &lt; ApplicationController
  before_action :valid_email?, only: [:send_message_email]
  
    # Shows the contact form page
    def contact
      @message = message(message_params)
    end
  
    # Sends the message.
    def send_message_email
      @message = message(message_params)
      if @message.valid?
        MessageMailer.new_message(@message).deliver_now
        redirect_to contact_path, notice: "Your messages has been sent."
      else
        flash[:alert] = "An error occurred while delivering this message."
        render :new
      end
    end    
  
    private
  
      def message_params
        params.require(:message).require(:name, :email, :content)
      end
  
      def valid_email?(email)
        VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
        email.present? &amp;&amp; (email =~ VALID_EMAIL_REGEX)
      end
  end
  </code></pre>
  
  <p>2) Contact form in app\views\static_pages\contact.html.erb:</p>
  
  <pre><code>&lt;%= form_for(message: params[:message], url: contact_path) do |f| %&gt;
    &lt;%= f.label :name %&gt; &lt;%= f.text_field :name, placeholder: 'Name', class: 'form-control' %&gt;
    &lt;%= f.label :email %&gt; &lt;%= f.email_field :email, placeholder: 'Email', class: 'form-control' %&gt;
    &lt;%= f.label :content %&gt; &lt;%= f.text_area :content, placeholder: 'Your message…', class: 'form-control' %&gt;
    &lt;%= f.submit "Send", class: "btn btn-primary" %&gt;
  &lt;% end %&gt;
  </code></pre>
  
  <p>3) Routes.rb</p>
  
  <pre><code>  get 'contact'           =&gt; 'static_pages#contact',  as: 'contact'
    post 'contact'          =&gt; 'static_pages#send_message_email'
  </code></pre>
  
  <p>4) App/views/message_mailer.text.erb (and html.erb)</p>
  
  <pre><code>&lt;%= @message[:name] %&gt; &lt;%= @message[:email] %&gt; wrote:
  &lt;%= @message[:content] %&gt;
  </code></pre>
  
  <p>5) App/mailers/message_mailer.rb</p>
  
  <pre><code>class MessageMailer &lt; ApplicationMailer
    default to: "myemail@example.com&gt;"
  
    def new_message(message)
      @message = message
      mail to: "myemail@example.com"
      mail from: @message[:email]
      mail subject: "Message from #{message[:name]}"
    end
  end
  </code></pre>
  
  <p>Now when I try to visit the contact form on the server, I get the error message: <code>param is missing or the value is empty: message</code>. It refers to the <code>params.require(:message).require(:name, :email, :content)</code> line. Not sure what I'm doing wrong. Changing it to <code>params.require(:message).permit(:name, :email, :content)</code> makes no difference.</p>