Building Your First Rails Application: Views and Controllers

Share this article

Welcome to the second part of our two-part tutorial. Last time, we installed Ruby on Rails, generated an application for shortening URLs and created the Model for it. Now we’re going to create the Controller for our application, write the View and see if we can get the application to work. You might want to just quickly review where we were up to in Part 1, and then push on.

Creating Your First Controller

Now that we’ve created our model (with Rails taking care of persistence and validation) it’s time to write a Controller. The Controller part of your applications handles taking the input (for example, data from the URL or the request body in the case of POST and PUT), and then interacting with the Model, as well as setting up data for the view portion.

RESTful Controllers

By default, Rails emphasizes a “RESTful” approach; that is to say, it uses the given HTTP verb (for example, GET, POST, PUT, DELETE) and well-organized urls to represent resources, leading to a general structure where code goes for operations on an object. It provides tools to handle basic CRUD (Create, Read, Update, Delete) actions on your data. In Rails terminology, the actions are typically:
  • index—An action that returns a listing of all resources; for example GET /urls will hit the index action on the URLs Controller, listing the known urls.
  • show—An action that performs a read operation for a single resource; for example GET /urls/1 will hit the show on the URLs Controller, showing the details of the URL with id 1.
  • new—The action to show a new object form, in our case, the new URL form; for example GET /urls/new will hit the new action on the URLs Controller and show the new URL form.
  • create—A post action to take the form data from the new action and to attempt to create a record; for example POST /urls will hit the create action on the URLs Controller, typically with some associated form data.
  • edit—Will show the form to edit a specific resource; for example GET /urls/1/edit will hit the edit action on the URLs Controller and show a form to edit the URL with id 1.
  • update—Will attempt to update the given resource; for example PUT /urls/1 will hit the update action on the URLs Controller and attempt to update the URL with id 1.
  • destroy—Will attempt to destroy a given resource; for example DELETE /urls/1 will hit the destroy action on the URLs Controller and attempt to destroy the URL with id 1.

Generating Our Controller

In our example, we’re going to cut it back from a full CRUD Controller and implement three basic actions: new, create, and show. When the user hits thenew action, it will render a new URL form. This will in turn hit the create action when we submit the form, and attempt to create the URL object. Finally, when the user hits the show action, we will redirect them to the stored URL. So, use the “Command Prompt with Ruby and Rails” option from the Start Menu to open the command prompt and change to the directory where you stored your code. We’ll generate a new URL Controller with a single new action by running:
rails generate controller urls new
The reason we only passed in the new action (instead of new, create, and show) is because Rails automatically generates a dummy view for each action included in the generator call. In this case, we only want a dummy view for the new action, so we exclude the others. Running the command should have created anapp/controllers/urls_controller.rb file and anapp/views/urls/new.HTML.erb file, as well as a few test files. For the moment, open up the Controller file and you’ll see something similar to:
class UrlsController < ApplicationController
  def new
  end

end
And, if you open config/routes.rb, you should also see it added a dummy route for us:
get "urls/new"
To start, while still in config/routes.rb, replace the above line with:
resources :urls, :only => [:show, :new, :create]
Save the file, switch back to the command prompt, and run rake routes. This will print out a list of all our routes. As you can see, Rails automatically set up three urls for us—GET /urls/new, GET /urls/:id, and POST /urlspointing to the new, show, and create actions respectively. If we start the server (using rails server) and hit the URL for the new action in the browser (http://localhost:3000/urls/new), you should now see a placeholder page similar to the image below.

Writing Our Controller Logic

In this case, our Controller logic is going to be very simple:
  • When the user hits the new page, it will set the @shortened_urlinstance variable to a new, unsaved URL object (we use @shortened_urlas our instance variable instead of @url, as the latter is used internally by Rails).
  • When the user submits the new form, we should attempt to create a new URL. If it is valid and saves, we’ll set a message telling the user the URL of their shortened link, and then we’ll redirect back to the Shorten page again.
  • If the URL is invalid, we’ll re-render the new form, this time showing the errors.
  • When the user hits the show action, we’ll redirect them to the URL.
So, with appcontrollersurls_controller.rb now open in your editor, replace all of code with:
class UrlsController < ApplicationController
  def new
    @shortened_url = Url.new
  end

  def create
    @shortened_url = Url.new(params[:url])
    if @shortened_url.save
      flash[:shortened_id] = @shortened_url.id
      redirect_to new_url_url
    else
      render :action => "new"
    end
  end

  def show
    @shortened_url = Url.find(params[:id])
    redirect_to @shortened_url.url
  end

end
Save the file. One important point to note here is that our choice of Model name—Url—has led to potentially confusing routes (for example new_url_url). To understand what this means exactly, we just need to remember the output ofrake routes. In there, we saw a route with the name new_url (among others). Rails automatically provides us with the new_url_url method (if our resources call in config/routes.rb had :posts instead of :urls, it would benew_post_url instead) as well as the _path equivalent; for examplenew_url_path. The difference between the two is that _url variants include the host, port, and protocol, whereas the _path variants include only the path and query string. In the above Controller code, you may have noticed the line containing:
flash[:shortened_id] = @shortened_url.id
If you’ve used a language like PHP before where you have a session for storing data, you’ll be pleased to know Rails also supports a session for sharing data between requests. On top of this, it also has a second feature—the flash—which is a session that automatically expires entries. When we store data in the flash (like the id of our shortened URL above), it will be removed after it has been accessed. This is particular useful for tasks like passing error and status messages around (as opposed to in the URL), as they’ll show once, and will disappear on subsequent pageloads. With all of that done, we now need to make one minor adjustment: we want to make it so if users hits the root page of our application (for examplehttp://localhost:3000/), they’re automatically redirected to the new URL form. In this case, it’s a fairly simple matter of doing two things:
  1. Remove the public/index.html file. This is just the default “Welcome to Rails” page, but when present it overrides our root, showing every user the “Welcome to Rails” page.
  2. In the config/routes.rb file, add a new line below our resources call.
The line we add should look like this:
root :to => redirect('/urls/new')
This tells Rails that when we hit the root URL (the equivalent of get '/' in our routes file), it should automatically redirect to the new URL action. To try it out, go back to the terminal, restart the Rails server if you closed it, and then point your browser to http://localhost:3000/. If all went as expected, your browser should have automatically been redirected tohttp://localhost:3000/urls/new.

Writing Your View

With the Controller and Model for Shorty ready to use, it’s time to add the final layer: a View. The View is the part that is actually shown to the user. By default, our Views are written in ERb: embedded ruby. ERb lets us embed bits of ruby into our HTML to generate dynamic pages. For example, to show the value of the URL attribute on a URL object, we’d use something like this in our View:
<%= @shortened_url.url %>
Then, at runtime, Rails will interpret the ruby portion to generate our HTML. Since our application is very simple, we’re only going to have to edit two views: the app/views/urls/new.html.erb file and our layout,app/views/layouts/application.html.haml.

Editing Your Layout

Layouts are the Rails way of defining the general structure or layout of the page. While the new.html.erb file is used for the HTML specific to our action (that is,for example the new action on another Controller will use another template), layouts are typically reused across several or all Actions. They are typically used to set up the general page structure; for example headers, menus, footers, and the like, while the page-specific stuff goes in your normal View. In this case, our default application.html.erb looks like:
<!DOCTYPE html>
<html>
<head>
  <title>Shorty</title>
  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
</head>
<body>

<%= yield %>

</body>
</html>
This is a very basic HTML5 page that does nothing but render the action view inside the body tag. The only aspect we’re going to change on this page (to make it reusable when we extend the application in the future), is when we shorten a link, we get a link to it at the top of the page. So, below the opening tag and above the line with yield on it, add the following:
<% if flash[:shortened_id].present? %>
  <p class='shortened-link'>
    The shortened url is available <%= link_to 'here',
url_url(flash[:shortened_id]) %>.
    (Right click and copy link to share it).
  </p>
<% end %>
The link_to in the code is simply a call to what is known as a helper method; in this case, something Rails defines for us that generates the HTML for a link with the given text (‘here’ in this example) pointing to the given URL (in this case, something like http://localhost:3000/urls/1) when a URL has been shortened. If no :shortened_id value is present in the flash, nothing will be shown, but when one is present it will output a link to it inside a paragraph tag.

Editing Your Form

With the layout updated to show our link post shortening, we now need to set up our form. First, open up app/views/urls/new.html.erb in your editor. By default, it should look like:
<h1>Urls#new</h1>
<p>Find me in app/views/urls/new.html.erb</p>
Delete that and replace it with:
<h1>Add a new URL</h1>
<%= form_for @shortened_url do |form| %>

  <p>
    <%= form.label :url, "Your URL:" %>
    <%= form.text_field :url %>
  </p>

  <% if @shortened_url.errors[:url].any? %>
    <p class='error-messages'>
      The given url <%= @shortened_url.errors[:url].to_sentence %>.
    </p>
  <% end %>

  <p class='buttons'>
    <%= form.submit "Shorten my URL" %>
  </p>

<% end %>
When run, this code will generate a form tag (with the correct Action and Method) with a bunch of other HTML inside of it. Inside here, it’ll generate a paragraph containing a label and text input for our URL field. In this case, we’re using a specific class of helpers via the form_for method. These are classes provided by Rails to make it easier to build up complex forms by handling generating fields and such. Next, we check if there are any errors on the URL field of the shortened URL object, and generate a paragraph tag with the class error-messages when there are. If the object doesn’t have any errors, it won’t output the HTML at all for this portion. Lastly, we generate a submit tag with the text “Shorten my URL,” finishing off our form.

Testing It Out

Going back to the console and starting the Rails server again (if it’s been stopped), reload http://localhost:3000/urls/new in your browser and you should see the following. If you click on Shorten my URL without any URLs entered into the Your URLfield, you will receive the following error page. If you enter a valid URL into the Your URL field and click Shorten my URL(for example http://google.com/), you’ll see the following image. As a bonus, by using a form builder, Rails provides a lot of extras. For instance, it automatically sets the value of the text field so that when we go to submit it the second time (after an error), it will insert a special token to prevent cross-site request forgery. In general, it makes it very easy to build up forms.

Wrapping It All Up

As you’ve seen, with very little code we’ve been able to build a rudimentary URL shortener (whether the URLs are actually shorter depends on your domain and the input URL, but it’s the idea in general that matters). We’ve only just scratched the surface of what you can do with Rails, but we have managed to cover a decent amount of Rails in a short period of time. Of course, the application we built is not without flaws. For example, whilst we validate that a URL is actually given, we don’t validate that it is a URL (and we blindly redirect to that value); hence, this isn’t the sort of code you’d actually deploy. Likewise, the workflow itself is very rudimentary. If you’re keen on what you’ve done so far, you now have a good starting place to learn more about Ruby on Rails. For example, you might go about adding better url validation, add a way to list all urls shortened, or even better, use the routes and a custom Action that works more like existing URL shorteners. For bonus points, you could switch to an alternative form builder like formtastic,which will generate even better in-depth HTML for us (removing the need to do tasks like printing the error messages manually). There is a wealth of documentation out there for Rails beginners, some better than others, and some of it requiring payment. I strongly suggest you start with the following resources:
  • The Official Rails Guides—free, lots of relevant information, and a great place to start.
  • The Ruby on Rails API—an API reference for the methods available from Rails.
  • Railscasts—a lot (250 and counting) of free, short screencasts on performing different tasks in Rails.
  • PeepCode—paid but professionally made screencasts on topics. Longer than Railscasts and generally more in depth.
  • Rails Tutorial—a free book (with paid downloadable versions) that serves as an in-depth guide to Rails.
I hope you enjoyed gaining a brief feel for the Rails way of doing things. Featured Image Credit: http://www.flickr.com/photos/wwworks/2475349116/

Frequently Asked Questions (FAQs) about Building Your First Rails Application: Views and Controllers

How do I generate a controller in Ruby on Rails?

Generating a controller in Ruby on Rails is a straightforward process. You can use the “rails generate controller” command followed by the name of the controller. For example, if you want to create a controller named “Posts”, you would type “rails generate controller Posts” in your terminal. This command will create several files, including a controller file, a views directory for your controller, and a test file for your controller.

What is the purpose of views in Ruby on Rails?

Views in Ruby on Rails are responsible for the presentation layer of your application. They define how the application’s data is displayed to the user. Views are typically written in an embedded Ruby (ERB) format, which allows you to embed Ruby code within HTML. This makes it easy to dynamically generate HTML based on your application’s data.

How do I create a view in Ruby on Rails?

To create a view in Ruby on Rails, you first need to have a corresponding controller. Once you have a controller, you can create a view by adding a new file to the “views” directory of your controller. The file should be named after the action it corresponds to and should have an .html.erb extension. For example, if you have a “Posts” controller and you want to create a view for the “index” action, you would create a file named “index.html.erb” in the “views/posts” directory.

What is the role of a controller in Ruby on Rails?

The controller in Ruby on Rails serves as the intermediary between models and views. It processes incoming requests from the web server, interacts with the model to retrieve or save data, and then compiles that data into a form that can be used by the view. The controller is also responsible for handling user input and sessions.

How do I link a view to a controller action in Ruby on Rails?

In Ruby on Rails, each controller action is automatically linked to a view of the same name. For example, if you have a “Posts” controller with an “index” action, Rails will automatically render the “index.html.erb” view in the “views/posts” directory after the action is performed. If you want to render a different view, you can use the “render” method in your controller action. For example, “render ‘new'” would render the “new.html.erb” view instead.

How do I use the command line to create a new Rails application?

To create a new Rails application, you can use the “rails new” command followed by the name of your application. For example, “rails new my_app” would create a new Rails application named “my_app”. This command creates a new directory with the same name as your application, and populates it with a default set of directories and files for a Rails application.

How do I generate a model in Ruby on Rails?

You can generate a model in Ruby on Rails using the “rails generate model” command followed by the name of the model. For example, “rails generate model Post” would create a new model named “Post”. This command creates a migration file for creating the database table, a model file for interacting with the table, and a test file for the model.

What is the purpose of the “rails server” command?

The “rails server” command starts a web server that allows you to interact with your Rails application in a web browser. By default, the server runs on port 3000, so you can access your application by navigating to “http://localhost:3000” in your web browser.

How do I add a route to my Rails application?

You can add a route to your Rails application by editing the “config/routes.rb” file. Inside this file, you can use the “get” method to define a route. For example, “get ‘posts/index'” would create a route for the “index” action of the “Posts” controller.

How do I use the Rails console?

The Rails console is a command line tool that allows you to interact with your Rails application. You can start the console with the “rails console” command. Inside the console, you can create, read, update, and delete records in your database, among other things.

Darcy LaycockDarcy Laycock
View Author

Darcy Laycock is a web application developer from Perth, Western Australia. By day, he writes code for The Frontier Group and by night he's a Code Monkey for Youth Tree (A youth-oriented organisation) from Perth and avid contributor to open source ruby projects.

InstallationNew To Rails
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week