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
- 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)). cd contact-form
rails generate model User name email likes_polar_bears:boolean next_country_to_live
OR simplyrails g
and the rest. Here we just created a User model, see it inapp/models
asuser.rb
. And in the database filedb/migrate
we will haveusers
table generated:
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
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.
<index, show, new, create, edit, update, delete>
The correct naming is super important. Your UsersController
file should look like this:
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:
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
.
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).
And this is what it looks like now:
The next thing for the views
is to make a show.html.erb
page to show an individual user details:
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:
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:
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.
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.
With this 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:
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:
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:
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.
Thanks for reading 😊 Go build stuff! #startToday
The code on GitHub: