Skip to content

Latest commit

 

History

History
158 lines (109 loc) · 7.41 KB

controllers.md

File metadata and controls

158 lines (109 loc) · 7.41 KB

Controllers

Learning Goals

  • Refresh on the http request cycle
  • Discuss how a request makes it way through a Rails application
  • Explore the role of controllers in a Rails application
  • Create a basic controller using the Rails generate command
  • Add an action to a controller
  • Define a basic route for our new controller action

Setting Up a Controller

A Rails Controller is the central manager of a Rails application. It takes requests from the web server, pulls information from data models and makes decisions. It then hands information to the views for rendering the data back to the user.

In Rails, we will build a separate class for each controller. The class is named after the type of resource it controls, and always ends with the word Controller. For example, in our books application, we might have a BooksController class and an AuthorsController class.

The things that a controller can do are called actions, and each action will be an instance method on a controller class.

We can, and eventually will, define our own custom actions, so that we can define more and more things for our controller to do. However, for today, we will be covering a lot of controller actions that are Rails conventions.

The first two controller actions that we will introduce are the index action and the show action. Our index action will usually mean that our controller will send back some important information. Our show action will usually mean that our controller will send back details of one thing.

Our BooksController might have an index action that sends back a list of books to the browser, and a show action that sends back details on one book. Each of those would be an instance method in the BooksController.

Many of these actions are so common that we use the same names for them every time - index and show are examples of this.

We'll start with just one controller (the BooksController) and one action (index). Rails can create a Controller for us with the following command:

rails generate controller Books

Note that Books (the controller name) is capitalized and pluralized.

The Controller Class

Rails places controller classes in the app/controllers folder. In the case of the Controller we just generated it will be in the books_controller.rb class.

Question: Does this follow our standard Ruby naming convention for classes and files?

Opening the Controller file you will find the code below:

# app/controllers/books_controller.rb
class BooksController < ApplicationController
end

Note that while we typed rails generate controller Books, Rails called the controller BooksController. This kind of shorthand is common in Rails - you'll quickly get used to it.

Question: What does < ApplicationController mean? How might this impact our class?

We've got a controller but no actions yet. To add any action of any name, we will create a method with that name inside of the controller class.

Therefore, to add the index action, create an empty method called index inside the controller class:

# app/controllers/books_controller.rb
class BooksController < ApplicationController
  def index
  end
end

This method won't stay empty for long, but first we've got a little more work to do.

Adding a Route

We've now created a controller (the BooksController class) and given it an action (the index method). However, Rails doesn't automatically know how to use this controller; we have to tell it.

To do so, we will introduce a new piece of Rails: the router. The responsibility of the router is to define which requests to this Rails server should go to which controller and which action defined within that controller. The router does its job with the help of a special configuration file that lives at:

config/routes.rb

In this file we will tell Rails where to send incoming HTTP requests.

Question: What are the parts of an HTTP request?

Answer The two pieces of an HTTP request that our router is interested in are the verb and the path.

Given the two parts of the http request, Rails can deduce which controller and action to use. The routes.rb file acts kind of like a big case statement, though the syntax is a little different.

The routefile should have a block of code filled in already. Add a line inside that block so it looks like this:

# config/routes.rb
Rails.application.routes.draw do
  # verb 'path', to: 'controller#action'
  get '/books', to: 'books#index'
end

What we've told the router to do is:

  • When you receive a GET request...
  • ...to the /books path...
  • ...go to the BooksController class and run the index action

Routing is a very important topic in Rails, and we'll definitely be coming back to this file later in the week. For now though, this one route will serve our purposes.

Fleshing Out the Controller

Question: According to our understanding of MVC, what should happen in a controller action?

Controller actions typically begin by gathering data from a model, and then use a view to turn that data into HTML. However, we haven't learned about either of those things yet!

To get us started, we will hard-code some data at the top of our file. This definitely not something you would normally do in Rails, but we want to take it piece-by-piece so bear with us.

In Rails, controllers communicate with views using instance variables. So, to make sure our soon-to-be-written view has access to our list of books, in our controller action we'll store a reference to the list in an instance variable.

# app/controllers/books_controller.rb
BOOKS = [
  { title: "Hidden Figures", author: "Margot Lee Shetterly"},
  { title: "Practical Object-Oriented Design in Ruby", author: "Sandi Metz"},
  { title: "Kindred", author: "Octavia E. Butler"}
]

class BooksController < ApplicationController
  def index
    @books = BOOKS
  end
end

Now, when we navigate to http://localhost:3000/books in our browser, we see...something is happening! It says we need a template, which we'll go over in the next lesson!

Summary

Routes

  • The Rails Router is responsible for dispatching (figuring out what to do with) a new HTTP request
    • It uses the verb and the path to select a controller action
  • Routes are defined in config/routes.rb
    • verb '/url/path', to: 'controller#action'
    • get '/books', to: 'books#index'
    • The order of routes matters

Controllers

  • A Rails Controller is responsible for handling a request and sending back a response
  • Each controller is a class, and each action is a method
    • Controller class names are usually pluralized, and always end in Controller, like BooksController
    • The controller#action pair in config/routes.rb must match the name of your controller class and action method exactly
      • books#show would look for BooksController and def show
    • A controller BooksController will be defined in the file app/controllers/books_controller.rb
  • To generate a controller run $ rails generate controller Books
  • Controllers use instance variables to communicate with views

Additional Resources