A Simple Rails Application for Gristmill's Up and Running Class
Ruby CoffeeScript JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Starting a New Application

Assuming you already have rails installed, you can create a new application with the "rails new" command. This command will create the directory structure and install dependencies.

rails new blog_app

Starting the Web Server

Navigate into the directory that was just created and start the development server.

cd blog_app
rails server

If you visit http://localhost:3000, you should see a welcome screen. This comes with every new Rails app. The first thing you have to do is delete it!

rm public/index.html

Now when you refresh the page you will be greeted with a nice error :)

No route matches [GET] "/"

Let's remedy the situation.

We will create a controller that we will declare as the root of our application.

rails generate controller home index

After the command finishes we need to tell Rails to use the Home controller and the index action as our root. We declare all application routes in the config/routes.rb directory. We need to add the following to the file:

BlogApp::Application.routes.draw do
  root :to => 'home#index'

If you go back to the browser you should see the error is resolved.

Creating a Resource

Rails comes with something called "scaffolding". It allows you to bootstrap a resource with standard database backed CRUD actions. When you run the scaffold command routes will be added to the config/routes.rb file and a controller, model and migration will be created. Everything needed for CRUD will work automatically.

Let's give it a whirl!

rails generate scaffold Post title:string body:text published:boolean

After a migration is added to your project (scaffolding adds one for you) you have to "migrate" your database. Migrations apply changes to your database, adding, changing or removing columns, tables and indexes.

Working with the database is really abstracted in Rails, so that most of the time you're working with Ruby rather than SQL!

You migrate the databse with the following command:

rake db:migrate

The Application Layout

Views are kept in app/views. The applications layout is kept in app/views/layouts. We are going to open up this file and add a link so that we can navigate in the browser to the resource we just created.

You can add this code anywhere in the file app/views/layouts/application.html.erb

<%= link_to "Posts", posts_path %>

so that it looks like this

<!DOCTYPE html>
  <%= stylesheet_link_tag    "application", :media => "all" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>

<%= link_to "Posts", posts_path %>
<%= yield %>


Reload the browser and click on the link and a few posts!

Adding Comments

The internet would be boring without trolling, so let's add support for it in our application. Now we aren't going to use scaffolding for comments. We could, but in this case it might be overkill. We will use a couple other rails commands to achieve the same thing but a little leaner.

To create just a model and a migration, we use this command

rails generate model comment post_id:integer body:text

And because a migration was added we will also need to migrate our database again.

rake db:migrate

Basic Associtations

We are going to wire up our two models with the has_many and a belongs_to associations.

The "post_id" we entered on the command line is the attribute that will be used as the foreign key to our Post relationship.

# app/models/post.rb
class Post < ActiveRecord::Base
  attr_accessible :body, :published, :title
  has_many :comments
# app/models/comment.rb
class Comment < ActiveRecord::Base
  attr_accessible :body, :post_id
  belongs_to :post

Now let's dive into the console!

The Console

You can play around with your entire app from a console session. Our Post and Comment models are available to us, so let's see if our associations are working.

To enter into a console session, just type from the root of your application directory

rails console

Once it boots up you can play around


comment = Post.last.comments.new


Working inside of the console is a great way to become familiar with the Rails environment. It is an incredibly useful and powerful tool.

Finishing up Comments

We have created a Commnet model and a migrations and our associations work as expected. We now need to support them in the interface.

Exit the console and enter this from the command line.

rails generate controller comments

We are only going to add one action to this controller. But We first have to edit our routes file. Add the following line to config/routes.rb

  resources :comments, :only => :create

so that it looks like this

BlogApp::Application.routes.draw do
  resources :posts

  resources :comments, :only => :create

  root :to => 'home#index'

The generated controller is empty by default. We're only adding one method, the create method.

Edit app/controllers/comments_controller.rb so that it looks like this

class CommentsController < ApplicationController
  def create
    @comment = Comment.new(params[:comment])

    redirect_to @comment.post

The create method will instantiate a new comment, save it and redirect the user to the comment's associated post.

Because we're showing comments on the PostsController show page, we will have to also instantiate them.

Find the show action in app/controllers/posts_controller.rb and add these two lines

@comments = @post.comments.all
@comment = @post.comments.new

So that it looks like

# GET /posts/1
# GET /posts/1.json
def show
  @post = Post.find(params[:id])
  @comments = @post.comments.all
  @comment = @post.comments.new

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @post }

Showing Comments in the Views

We next need to add a couple of partials to the app/views/comments directory that was just created.

Add the following two files to app/views/comments directory. And note that each of these files starts with an underscore "_".

touch app/views/comments/_comment.html.erb
touch app/views/comments/_form.html.erb

These are known as "partials". Partials are designated by an underscore in the filename. Partials are included by other views and help keep your view files small and clean.

Add these two lines to app/views/posts/show.html.erb

<%= render "comments/form" %>
<%= render @comments %>

So that the file looks like

<p id="notice"><%= notice %></p>

  <%= @post.title %>

  <%= @post.body %>

  <%= @post.published %>

<%= render "comments/form" %>
<%= render @comments %>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

In the form partial (app/views/comments/_form.html.erb) add this code

<%= form_for @comment do |f| %>
  <%= f.hidden_field :post_id %>
  <%= f.text_area :body %>
  <%= f.submit "Submit", :disable_with => 'Submitting' %>
<% end %>

And in the _comment.html.erb file add this code

<%= div_for comment do %>
  <strong><%= comment.body %></strong>
  <%= distance_of_time_in_words_to_now comment.created_at %>
<% end %>

That's it!

You now have a working Ruby on Rails application!


Ruby on Rails has a vibrant community. The following people are pretty influential in the Rails community.

Awesome Rails Core Developers

Community Members Involved with Rails Education

Great Resources for Learning Rails

Educational Ruby and Rails Newsletter