[Ruby on Rails] MVC contact form with validations

🦋Allegra
7 min readJul 3, 2018

So let's make a contact form. We all need some contact, right.

Structure of aproach:

  • Generate a model and set up database
  • Controller + routes
  • Views + partial _form
  • Validations + flash errors

1. Model + database

  1. We start with rails new contact-form in your terminal (assuming you’re where you want to be (in terms of preferred directory, not life)).
  2. cd contact-form
  3. rails generate model User name email likes_polar_bears:boolean next_country_to_live OR simply rails g and the rest. Here we just created a User model, see it in app/models as user.rb. And in the database file db/migrate we will have users table generated:
This is what “rails g model User name email likes_polar_bears:boolean next_country_to_live” will generate.

As you can see name, email and next_country_to_live defaults to a string, and likes_polar_bears I chose to be boolean, you can choose them to be integer, date time, float, up to you what values you want here.

4. In db/migrate folder you will see 20180702195423_create_users.rb, this is the name of the migration we are about to run. The number in the front is a timestamp 2018 07 02 19:54:23 of the creation.

Run rake db:migrate

Something like this will show if your migration was successful.

5. So now we have a database! To verify, now there is a schema.rb file in your migrate folder. Have a look at it. If there is something you want to change, you can always run rake db:rollback, make changes in your migration file (the one with the timestamp) and rake db:migrate again. Warning: you will loose data.

2. Controller

To make a controller, navigate to app/controllers folder and create a new file users_controller.rb . Or generate it with rails g controller <controller_name>

class UsersController < ApplicationController 
.............
end

Which means that our UsersController inherits from ApplicationController, which inherits from ActionController::Base.

Inside your UsersController define all 7 CRUD methods.

This is what CRUD stands for.

<index, show, new, create, edit, update, delete>

The correct naming is super important. Your UsersController file should look like this:

The REST of the code.

Notice destroy is used in rails and ruby for http verb delete.

In create and update we need to use the private method user_params that we created at the bottom. In Rails we need to permit params explicitly, we can’t just pass all params, and because of that we are able to make a form that allows the user to only edit the information we allow to be edited. But for now let’s just make it simple and allow users to edit all the params.

+ ROUTES.RB

They live in config folder. Let's take an easy route and type in resources :users since we are using all 7. This is the shortest version, but I recommend looking into explicit versions to understand what is really happening here.

Examples:resources :users, only: [:index, :new, :create]get ‘/users/:id’, to: ‘users#show’, as: ‘user’

Type in rake routes in the terminal to see all the routes/paths we now have:

Our rake routes.

3. Views.

In app/views create a users folder, in this folder let’s create 4 files: index.html.erb, show.html.erb, new.html.erb, edit.html.erb

Naming is super important here too.

Index will display all our users, then we will be able to click to see an individual user by using show page, new will have a form to add a new user and edit will have a form to edit the user’s details.

index page:

Keyboard shortcuts: type in any html element, like h3 or div and hit tab, will become <h3></h3>, and for the <%= famous %> press = and tab.

index.html.erb

Type the above code, which iterates through all the users and prints out the details. Let's check if it’s working before we do anything else. It’s a good practise to check if your code is working frequently. Go to your terminal and run rails server rails s or rails server, then go to http://localhost:3000/users . To close the server, hit ctrl + C

You should see All users: and nothing else, because we don't have any new users yet. Let’s add some. There are 3 ways to do it (maybe more, but for now I can only think of 3). Pick what works for you:

First: go to the db/migrate/seeds.rb file and enter:

users = User.create(name: “Lapinas”, email: “lapinas@grazuolis.com”, likes_polar_bears: true, next_country_to_live: “Mother Earth”)

Then run rake db:seed in your terminal to seed your database with this data. Then run the rails server again and you will see it there.

Second: you can do it in rails c or rails console, exit when you had enough.

Third: to create a new user form in the /users/new.html.erb This is what we are going to do now.

THE _FORM

Let’s jump ahead here and instead of doing pretty same stuff in new and edit pages, let’s make one form that the two shares. This is called partial. DRY = don’t repeat yourself

In views/users folder create a _form.html.erb file and let’s make our form in there. At the same time, in new.html.erb file type in:

<h1>New user:</h1><%= render “form” %>

And in edit.html.erb file:

<h1>Edit <%= @user.name %> profile: </h1><%= render “form” %>

Here we just told them to use the form we’re about to create, notice how “_” disappears with rendering. We have a _form.html.erb and we render "form".

So now in _form.html.erb enter:

(leave your rails server running and refresh anytime you make changes).

_form.html.erb

And this is what it looks like now:

Our fresh form!

The next thing for the views is to make a show.html.erb page to show an individual user details:

show.html.erb

Now is all WORKING!!! We can use our form to create new users and have them displayed in /users/:id, i.e., /users/1

When you get your code working, you know what time it is:

You thought.

It’s IMPROVEMENTS TIME:

Let's link our pages, so that we can navigate from one page to another. Let's change our index.html.erb code, so that we have a link to New user at the top, and then a list of user names as link to individual pages:

index.html.erb

In show.html.erb let’s add an EDIT link, which would take us to the edit form with the pre-filled current values. There is a link Back to all users too.

show.html.erb

in new.html.erb add:

<div>
<%= link_to “Cancel”, users_path %>
</div>

in edit.html.erb add:

<div>
<%= link_to “Cancel”, user_path %>
</div>

And also we need a delete button here. Which will look like:

<%= form_tag user_path(@user), method: "delete" do %>
<%= submit_tag "Delete #{@user.name}" %>
<% end %>

Dropdown selection and check boxes

Let’s make our form to look like this, so that our user can tick a box if they like polar bears (true/false) and they can select a country from the countries list.

Form with selection dropdown and a check box.

With this code:

_form.html.erb code
check_box :name_of_param, {}, "true", "false"select :name_of_param, ["array", "of", "options"]

VALIDATIONS

We want to prevent users from entering invalid details, that’s where validations come in.

In order to do that we will need to edit: model, controller (create & update methods), views (new & edit files).

First: app/models/user.rb to have this code:

validation code is user.rb

Here I validate my user’s input by uniqueness (it can’t be the same as those that already exist) and presence (it can’t be blank). For the name input I also specified that the allowed length is between 2–20 characters and only letters. There are better ways (or gems?) to validate an email address, but for now let’s leave it like this.

Second: in app/controllers/users_controller.rb make your create and update methods to look like this:

This code will validate your user_params and redirect accordingly

Third: in app/views/users : new.html.erb and edit.html.erb enter this code:

<% if flash[:errors] %>
<% flash[:errors].each do |error| %>
<li style="color:red;"> <%= error %> </li>
<% end %>
<% end %>

Now if a user tries to submit a blank form, our validations will do the work for us and throw the errors:

Error messages.

Et voilà! That’s it for now. Go get some water and think of what other features you’d like to add here.

THE END.

This a step-by-step guide to get you started, feel free to modify the code and try different things. byebug is an awesome debugging tool which you should use to inspect your params, etc. The same way you can generate more models here and then define relationships such as has_many /belongs_to, and then let all the fun begin.

MODEL-VIEW-CONTROLLER

Thanks for reading 😊 Go build stuff! #startToday

The code on GitHub:

--

--