Kristiyan Tsvetanov
Kristiyan Tsvetanov

Reputation: 1047

Rails, contact form in a one-page

I am trying to put a contact form in a one-page web page using mail_form. However, I find it hard to follow the instructions as they assume I have a view specifically for the form but in my case everything is in a controller visitors_controller. According to the instructions, there should be a controller looking like this:

class ContactsController < ApplicationController
def new
    @contact = Contact.new
  end

def create
   @contact = Contact.new(params[:contact])
   @contact.request = request
    if @contact.deliver
      flash.now[:notice] = 'Thank you for your message. We will contact you soon!'
    else
      flash.now[:error] = 'Cannot send message.'
      render :new
    end
  end

end

And the view would look like this:

<%= simple_form_for @contact, html: {class: 'form-horizontal' } do |f| %>
    <%= f.input :name, :required => true %>
    <%= f.input :email, :required => true %>
    <%= f.input :message, :as => :text, :required => true %>
    <div class= "hidden">
      <%= f.input :nickname, :hint => 'Leave this field blank!' %>
    </div>
      <%= f.button :submit, 'Send message', :class=> "btn btn-primary" %>
  <% end %>

How to achieve the same in my visitors_controller and view? The controller currently looks like this if it is important

class VisitorsController < ApplicationController
    def index
    end
end

Upvotes: 1

Views: 321

Answers (1)

GoGoCarl
GoGoCarl

Reputation: 2519

At the end of the day, it's just a form, nothing special. You just need to tell the form where to POST, and handle it in a target. By default, it would post to a separate controller, but that's not necessary, just easiest.

To post elsewhere, it would work just like any other form that posts to a specific URL.

First, you need to make the URL.

config/routes.rb:

resources :visitors do
  post :contact, on: :collection
end

This will add a route contact_visitors_path to your application. This is the target to which your form will POST.

Then, add support for this route in visitors_controller:

def contact
  @contact = Contact.new(params[:contact])
  @contact.request = request
  if @contact.deliver
    flash.now[:notice] = 'Thank you for your message. We will contact you soon!'
    redirect_to visitors_path # Go back to the index page
  else
    flash.now[:error] = 'Cannot send message.'
    render :index # Instead of :new, as we submit from :index
  end 
end

Next, add support for this form on the index page (the page the form appears, like "new" in the example):

def index
  @contact = Contact.new
end

Finally, just need to tell the form where to post.

= simple_form_for @contact, url: contact_visitors_path, html: {class: 'form-horizontal' }

Now, the form is pointing to your visitors_controller, and being handled by your custom method. Everything else works the same.

Upvotes: 3

Related Questions