Nick Bucciarelli

Hacker, instructor, yadda yadda.

Creating a Basic Rails Application

| Comments

I’m going to teach you how to create a basic rails application STEP BY STEP. There will be images and code for each step as well. I hope this works for you guys.

I know there are no tests written, but this is just for my students to create a ‘scaffold’ of controller/models.

There are a few dependencies as well:

  • rvm
  • Sublime text
  • Sublime text alias (sub) that will open your project folder

In this first step, I want to create myself a new project folder. I am going to call this project “contact_list” as that is what we will be creating together, a 21st century Rolodex!

1
2
3
% cd ~/projects/
% mkdir contact_list
% cd contact_list

This next will will set up dependencies. Anyone who has been in a ruby project for long enough will know that RVM is huge. We will be using that in this project. To make gemset management easier, we will be creating a “.rvmrc” file.

1
2
% touch .rvmrc
% sub .

Inside of that “.rvmrc” file, we need to create our specific gemset. This command will force your computer to create the gemset if you haven’t yet.

1
rvm 2.1@contact_list --create

This command should reload your current directory. The following screenshot will display what output you SHOULD get. If you do not get it, you need to cd out of your directory, then CD back in.

1
% cd .

Screenshot of stuff

Now, we are going to create our Rails project. To start, we need to install our Rails gem. After our gem is installed, we create a new project inside of our current directory with ‘rails new .’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
% gem install rails
% rails new .

       exist
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/assets/images/.keep
      create  app/mailers/.keep
      create  app/models/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/bundle
      create  bin/rails
      create  bin/rake
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/secrets.yml
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookies_serializer.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  lib/assets
      create  lib/assets/.keep
      create  log
      create  log/.keep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/robots.txt
      create  test/fixtures
      create  test/fixtures/.keep
      create  test/controllers
      create  test/controllers/.keep
      create  test/mailers
      create  test/mailers/.keep
      create  test/models
      create  test/models/.keep
      create  test/helpers
      create  test/helpers/.keep
      create  test/integration
      create  test/integration/.keep
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
         run  bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Installing rake 10.3.0
Using i18n 0.6.9
Using json 1.8.1
Using minitest 5.3.3
Using thread_safe 0.3.3
Using tzinfo 1.1.0
Using activesupport 4.1.0
Using builder 3.2.2
Using erubis 2.7.0
Using actionview 4.1.0
Using rack 1.5.2
Using rack-test 0.6.2
Using actionpack 4.1.0
Using mime-types 1.25.1
Using polyglot 0.3.4
Using treetop 1.4.15
Using mail 2.5.4
Using actionmailer 4.1.0
Using activemodel 4.1.0
Using arel 5.0.1.20140414130214
Using activerecord 4.1.0
Using bundler 1.6.1
Installing coffee-script-source 1.7.0
Installing execjs 2.0.2
Installing coffee-script 2.2.0
Using thor 0.19.1
Using railties 4.1.0
Installing coffee-rails 4.0.1
Using hike 1.2.3
Using multi_json 1.9.2
Installing jbuilder 2.0.6
Installing jquery-rails 3.1.0
Using tilt 1.4.1
Installing sprockets 2.11.0
Using sprockets-rails 2.1.3
Using rails 4.1.0
Installing rdoc 4.1.1
Installing sass 3.2.19
Installing sass-rails 4.0.3
Installing sdoc 0.4.0
Installing spring 1.1.2
Installing sqlite3 1.3.9
Installing turbolinks 2.2.2
Installing uglifier 2.5.0
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:

<= 1.8.6 : unsupported
 = 1.8.7 : gem install rdoc-data; rdoc-data --install
 = 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

Now, we’re going to start our server to make sure everything is kosher. Let’s start it and check it out!

1
% rails server

We have a rails project. This is the screen you guys should be getting. This is the “Welcome Aboard” message you get when you start every project.

Screenshot of stuff

I want to get rid of the “Welcome Aboard” screen and start developing my own application, so I need to go into “config/routes.rb” and set up a root route. This will be where my application starts. For instance, if someone comes to my application at “www.nickscontactlist.com”, this root route will be how it starts. The following code is telling it to go to a “Home” Controller’s “Index” action.

1
2
3
Rails.application.routes.draw do
  root 'home#index'
end

After this, I refresh my page to see what it tells me. Remember, you need to code a little then test the output.

Screenshot of stuff

Awesome! This is the error I wanted. I need to initialize a Home Controller now! Remember, Controller’s are generally pluralized! This one will be different. This is my landing page, hence “Home”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rails generate controller home

      create  app/controllers/home_controller.rb
      invoke  erb
      create    app/views/home
      invoke  test_unit
      create    test/controllers/home_controller_test.rb
      invoke  helper
      create    app/helpers/home_helper.rb
      invoke    test_unit
      create      test/helpers/home_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/home.js.coffee
      invoke    scss
      create      app/assets/stylesheets/home.css.scss

Awesome. I have my Home controller created. Let’s refresh the page and see what happens.

Screenshot of stuff

This is a new error. I need to go into my newly created Home Controller to create my “index” action now.

1
2
3
4
class HomeController < ApplicationController
  def index
  end
end

Let’s refresh the page and see what happens.

Screenshot of stuff

I now need to create an index template. The template name matches the action name. Notice I am using the application to drive how I create things. Way cool.

1
touch app/views/home/index.html.erb

Let’s put something inside of the file as well.

1
<h1>Yey</h1>

Cool! Now, let’s create some more routes so I can do more things.

1
2
3
4
5
Rails.application.routes.draw do
  root 'home#index'

  resources :contacts
end

Let’s look at all of the routes I just created.

1
2
3
4
5
6
7
8
9
10
11
12
% rake routes

      Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            home#index
    contacts GET    /contacts(.:format)          contacts#index
             POST   /contacts(.:format)          contacts#create
 new_contact GET    /contacts/new(.:format)      contacts#new
edit_contact GET    /contacts/:id/edit(.:format) contacts#edit
     contact GET    /contacts/:id(.:format)      contacts#show
             PATCH  /contacts/:id(.:format)      contacts#update
             PUT    /contacts/:id(.:format)      contacts#update
             DELETE /contacts/:id(.:format)      contacts#destro

Let’s throw some more content in index.html.erb. I want to be able to create new data now, so let’s throw a “New Contact” link in there as well.

1
2
3
  <h1>Yey</h1>

  <%= link_to "New Contact", new_contact_path %>

Let’s refresh the page and see what happens. Let’s ALSO click the “New Contact” link.

Screenshot of stuff

Uh oh! I need to create a Contacts Controller now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rails generate controller contacts

      create  app/controllers/contacts_controller.rb
      invoke  erb
      create    app/views/contacts
      invoke  test_unit
      create    test/controllers/contacts_controller_test.rb
      invoke  helper
      create    app/helpers/contacts_helper.rb
      invoke    test_unit
      create      test/helpers/contacts_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/contacts.js.coffee
      invoke    scss
      create      app/assets/stylesheets/contacts.css.scss

Let’s refresh the page.

Screenshot of stuff

My controller is created, now I need to create the new actions.

1
2
3
4
class ContactsController < ApplicationController
  def new
  end
end

Cool, let’s refresh the page.

Screenshot of stuff

Now, I need to create a template to match my action name.

1
% touch app/views/contacts/new.html.erb

Refresh the page and look at a blank screen! Now let’s put some stuff inside of it.

1
2
3
4
5
6
7
8
<h1>New Contact</h1>

<%= form_for @contact do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  <br>
  <%= f.submit %>
<% end %>

I want to create a new contact, so I put a form in there. Let’s fresh the page and see what happens.

Screenshot of stuff

I need to then go create some data to give to my form. I do that inside of the Controller. Let’s do that!

1
2
3
4
5
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end
end

Awesome, data is created, let’s refresh and see what happens.

Screenshot of stuff

Oh no! I am missing my Model! Let’s create one.

1
2
3
4
5
6
7
% rails generate model contact
      invoke  active_record
      create    db/migrate/20140416191313_create_contacts.rb
      create    app/models/contact.rb
      invoke    test_unit
      create      test/models/contact_test.rb
      create      test/fixtures/contacts.yml

Refresh the page and let’s see what happens.

Screenshot of stuff

Oh, I created a Model and I forgot to add data to it so it’s telling me to migrate. Let’s go fill in the migration.

1
2
3
4
5
6
7
8
class CreateContacts < ActiveRecord::Migration
  def change
    create_table :contacts do |t|
      t.string :name
      t.timestamps
    end
  end
end

Now, let’s run the migration.

1
2
3
4
5
6
% rake db:migrate

== 20140416191313 CreateContacts: migrating ===================================
-- create_table(:contacts)
   -> 0.0014s
== 20140416191313 CreateContacts: migrated (0.0015s) ==========================

Wooo! Got some data fields. Let’s fresh the page now:

Screenshot of stuff

Hell yeah. Let’s fill in the form and click “Create Contact”.

Screenshot of stuff

Oh no! Let’s go create a “new” action inside of our Contacts Controller.

1
2
3
4
5
6
7
8
9
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create params[:contact]
  end
end

Cool. Let’s go back to the form and fill it out again. Click “Create Contact”.

Screenshot of stuff

Oooo. This is a new Rails thing. We need to add a method that whitelists parameters inside of our controller. We do it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

Let’s try to submit again.

Screenshot of stuff

Now, I need to either tell my action to render something, or I need to redirect. Let’s redirect to our root page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

Refresh and fill out the form again.

Screenshot of stuff

It redirected correctly, but no data is showing up. Let’s render out some data to the user.

1
2
3
4
5
6
7
8
<h1>Yey</h1>

<%= link_to "New Contact", new_contact_path %>
<br>
<% @contacts.each do |contact| %>
  <%= contact.name %>
  <br>
<% end %>

Let’s refresh the page.

Screenshot of stuff

I forgot to define my @contacts variable! Let’s go do that inside of the Home controller.

1
2
3
4
5
class HomeController < ApplicationController
  def index
    @contacts = Contact.all
  end
end

Let’s see what happens when I refresh.

Screenshot of stuff

Oooo data. Let’s see what I want to do next:

1
2
3
4
5
6
7
8
9
10
11
12
% rake routes

      Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            home#index
    contacts GET    /contacts(.:format)          contacts#index
             POST   /contacts(.:format)          contacts#create
 new_contact GET    /contacts/new(.:format)      contacts#new
edit_contact GET    /contacts/:id/edit(.:format) contacts#edit
     contact GET    /contacts/:id(.:format)      contacts#show
             PATCH  /contacts/:id(.:format)      contacts#update
             PUT    /contacts/:id(.:format)      contacts#update
             DELETE /contacts/:id(.:format)      contacts#destro

Let’s make an “Edit” link next for each contact with the route we found above.

1
2
3
4
5
6
7
8
9
<h1>Yey</h1>

<%= link_to "New Contact", new_contact_path %>
<br>
<% @contacts.each do |contact| %>
  <%= contact.name %>
  <%= link_to "Edit", edit_contact_path(contact) %>
  <br>
<% end %>

Let’s refresh and click it.

Screenshot of stuff

Cool. Let’s go create that action.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

  def edit
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

Let’s refresh and click the “Edit” link again.

Screenshot of stuff

Let’s create our “Edit” template now.

1
% touch app/views/contacts/edit.html.erb

And let’s populate it with something.

+ erb
1
<h1>Edit Contact</h1>

Refresh the page.

Screenshot of stuff

Woo woo! Let’s put a form in there to edit some data.

1
2
3
4
5
6
7
8
<h1>Edit Contact</h1>

<%= form_for @contact do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  <br>
  <%= f.submit %>
<% end %>

Refresh and see what happens.

Screenshot of stuff

Now I need to go into my Controller and make that variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

  def edit
    @contact = Contact.find params[:id]
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

Refresh and see what happens.

Screenshot of stuff

Let’s fill in some data and click the “Update Contact” button.

Screenshot of stuff

Cool! Let’s go put that update action in there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ContactsController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

  def edit
    @contact = Contact.find params[:id]
  end

  def update
    @contact = Contact.find params[:id]
    @contact.update_attributes que_params
    redirect_to root_path
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

And submit the data again.

Screenshot of stuff

Woo woo! Let’s see what route we want to do next

1
2
3
4
5
6
7
8
9
10
11
12
% rake routes

      Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            home#index
    contacts GET    /contacts(.:format)          contacts#index
             POST   /contacts(.:format)          contacts#create
 new_contact GET    /contacts/new(.:format)      contacts#new
edit_contact GET    /contacts/:id/edit(.:format) contacts#edit
     contact GET    /contacts/:id(.:format)      contacts#show
             PATCH  /contacts/:id(.:format)      contacts#update
             PUT    /contacts/:id(.:format)      contacts#update
             DELETE /contacts/:id(.:format)      contacts#destro

Let’s have a link that shows each individual contact now:

1
2
3
4
5
6
7
8
9
<h1>Yey</h1>

<%= link_to "New Contact", new_contact_path %>
<br>
<% @contacts.each do |contact| %>
  <%= link_to contact.name, contact_path(contact) %>
  <%= link_to "Edit", edit_contact_path(contact) %>
  <br>
<% end %>

Let’s click our newly created links.

Screenshot of stuff

Cool. Let’s create the show action.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class ContactsController < ApplicationController
  def show
    @contact = Contact.find params[:id]
  end

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

  def edit
    @contact = Contact.find params[:id]
  end

  def update
    @contact = Contact.find params[:id]
    @contact.update que_params
    redirect_to root_path
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

Refresh the page and see what happens.

Screenshot of stuff

Let’s go create our template.

1
touch app/views/contacts/show.html.erb

Throw some stuff in there.

1
2
3
4
5
<h1>Show data</h1>

<%= @contact.name %>

<%= link_to "Home", root_path %>

Let’s see what to do next!

1
2
3
4
5
6
7
8
9
10
11
12
% rake routes

      Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            home#index
    contacts GET    /contacts(.:format)          contacts#index
             POST   /contacts(.:format)          contacts#create
 new_contact GET    /contacts/new(.:format)      contacts#new
edit_contact GET    /contacts/:id/edit(.:format) contacts#edit
     contact GET    /contacts/:id(.:format)      contacts#show
             PATCH  /contacts/:id(.:format)      contacts#update
             PUT    /contacts/:id(.:format)      contacts#update
             DELETE /contacts/:id(.:format)      contacts#destro

Let’s make a delete link

1
2
3
4
5
6
7
8
9
10
<h1>Yey</h1>

<%= link_to "New Contact", new_contact_path %>
<br>
<% @contacts.each do |contact| %>
  <%= link_to contact.name, contact_path(contact) %>
  <%= link_to "Edit", edit_contact_path(contact) %>
  <%= link_to "Delete", contact_path(contact), method: :delete %>
  <br>
<% end %>

Let’s click the link and see what happens.

Screenshot of stuff

Let’s make a delete link!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class ContactsController < ApplicationController
  def show
    @contact = Contact.find params[:id]
  end

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.create que_params
    redirect_to root_path
  end

  def edit
    @contact = Contact.find params[:id]
  end

  def update
    @contact = Contact.find params[:id]
    @contact.update_attributes que_params
    redirect_to root_path
  end

  def destroy
    @contact = Contact.find params[:id]
    @contact.delete
    redirect_to root_path
  end

private
  def que_params
    params.require(:contact).permit(:name)
  end
end

All dooooooonnnnnnnnneeee!

Screenshot of stuff

Comments