As we learned previously, Rails uses views to show back-end data to a user. How does a Rails application know what data to show? When is an index view rendered rather than a show view? How does Rails control all of this stuff? You guessed it, with controllers. Today we'll go over how a Rails application makes data and actions available to these views using controllers.
This post is the second in a multi-part series on building a Rails application. Check out part 1 here.
Let's look at how PowerUp uses controllers.
Here are some additional resources: CodeSchool's Rails tutorial series has a lesson dedicated to controllers. RailsGuides are typically my first stop for Rails questions, and they have an excellent section on how routes and controllers interact.
Organizing Rails apps with RESTful controllers
Because Rails is designed as a web application framework, setting up our application's actions is centered around using HTTP verbs (GET, PUT/PATCH, POST, DELETE) to keep our code organized. Rails conventions give us a way to accomplish our typical database actions (create, read, update, destroy, or CRUD) using HTTP verbs. Further down the line, our views and paths will also be organized around these actions. Here's a list of the actions using
users as an example:
indexmethod returns a list of all of the users. HTTP verb:
showreturns a specific user. Can be used to retrieve a user's info. HTTP verb:
newreturns a form for creating a new user. Is related to the
createaction. HTTP verb:
createcreates a new user by adding its record to the database. HTTP verb
editreturns a form for changing a user's info in the database. Is related to the
updateaction. HTTP verb:
updatechanges a user's record in the database. HTTP verb:
destroydeletes a user's record in the database. HTTP verb;
Next, let's generate a controller and start writing some Ruby code.
Generating the Controller in Rails
A Rails application makes it easy to generate controllers quickly. To do so, go to your terminal and first make sure you are in your application's directory (this gets me every time). Next, enter the following command:
rails generate controller users index
Let's break this command down to see what's happening. We are telling Rails to create a
controller (not a model, which is the other option), to name it
users, and to create an action in the controller called
index as a Ruby method. While Rails can create these actions for us, we will always have the option of writing additional Ruby methods in any controller we generate.
We should now have two new files in our Rails app;
app/views/index.html.erb. The ERB view file should be familiar from our previous look at Rails views. If we open the
users_controller.rb, it should look like this:
class UsersController < ApplicationController def index end end
This file is now our blank slate. From the controller, a Rails developer directs how information in the application is stored and rendered, and can direct how a user navigates the application.
Let's look at how some of the actions we previously defined would be implemented in our users controller. Here's the
def index @users = User.all end
index defines the instance variable
@users so that we may access this list of all users later on in the application, typically in the
index.html.erb view. This is the most basic RESTful controller action, but wouldn't it be nice if we could create a new user as well? How would we write that action so it handles the database create AND the rendering of a specific path? With a little Ruby knowledge and a some Rails magic, we can write all of this in one method. Let's take a look:
def create @user = User.new(user_params) if @user.save redirect_to user_path(@user), :notice => "Thanks for signing up! Here's your profile page." else render :new end end
What's going on here? The
create method is handling a few things for us:
@useras a new user.
- Checking if an attempt to save the user record is succssful. If it is, taking the user to the user show view (a "user profile"), and showing a confirm notice
- If the attempt fails, redirecting back to the user new form.
The Rails magic in this method comes from the helpers like
redirect_to helper does exactly what it says: redirects the user to a specific view. The
user_pathis particular to the user show view, but you'll see that all of your application's view have some sort of
_path helper assigned to it. Enter
rake routes in your terminal to see a list of all of the available view paths. The
render helper is another way to point to a particular view.
A successful new user signup using the create method.
While we've gone over two of the RESTful actions in a Rails controller, they are others to consider when building your Rails application. Try writing the controller methods for some of the actions and see what you come up with. A typical Rails app will have at least one resource that has "full CRUD," or uses all of the controller actions. We'll explore Rails models and how they fit in with our controllers and views in the next installment.