Controller

The Rails controller is the logical centre of your application. It coordinates the interaction between the user, the views, and the model. The controller is also a home to a number of important ancillary services.

  • It is responsible for routing external requests to internal actions. It handles people-friendly URLs extremely well.
  • It manages caching, which can give applications orders-of-magnitude performance boosts.
  • It manages helper modules, which extend the capabilities of the view templates without bulking up their code.
  • It manages sessions, giving users the impression of an ongoing interaction with our applications.

The following diagram explains how the controller interacts with the model and the view layer −

Ruby on Rails Controller

The process for creating a controller is very easy, and it’s similar to the process we’ve already used for creating a model.

Make sure that you have already created the book model and performed migrations

rails generate model Book title:string author:string price:integer
rails db:migrate

We will create the BooksController here −

rails generate controller Books
  create  app/controllers/books_controller.rb
  invoke  erb
  create    app/views/books
  invoke  test_unit
  create    test/controllers/books_controller_test.rb
  invoke  helper
  create    app/helpers/books_helper.rb
  invoke    test_unit

Notice that you are capitalizing Book and using the singular form. This is a Rails paradigm that you should follow each time you create a controller.

This command accomplishes several tasks, of which the following are relevant here −

It creates a file called app/controllers/book_controller.rb. If you look at book_controller.rb, you will find it as follows −

classBooksController<ApplicationControllerend
  • Controller classes inherit from ApplicationController, which is the other file in the controllers folder: application.rb.
  • The ApplicationController contains code that can be run in all your controllers and it inherits from Rails ActionController::Base class.

In the MVC architecture, a route maps a request to a controller action. A controller action performs the necessary work to handle the request, and prepares any data for the view. A view displays data in a desired format.

We need to define actions in the BooksController class to handle the requests. Actions are instance methods in the class. Note that it is upto you what name you want to give to these action methods, but better to give relevant names.

By default, the rails generate controller command creates the controller file (books_controller.rb) but does not include any actions unless explicitly specified. Let us define index(), show() and create() actions in the BooksController class.

classBooksController<ApplicationControllerdefindexenddefshowenddefcreateendend

Note that you can generate a controller with specific actions (e.g., index, show, create, etc.), if you include them in the command:

rails generate controller Books index show create

Implementing the create Method

The create action is expected to be invoked by the router in response to POST /books request. It creates a new book object and returns the JSON response of newly created object.

defcreate@book=Book.new(book_params)[email protected]
  render json:@book, status::createdelse
  render json:@book.errors, status::unprocessable_entityendend</pre>

The first line creates a new instance variable called @book that holds a Book object built from the data, the user submitted. The book_params method is used to collect all the fields from object :books. The data was passed from the new method to create using the params object.

The next line is a conditional statement that renders the book data in JSON if the object saves correctly to the database. If it doesn't save, the user is sent back error message.

Implementing the show Method

The show action displays the details of a book object of a certain ID passed by GET /books/:id request.

defshow@book=Book.find(params[:id])
render json:@bookend</pre>

The show method's @book = Book.find(params[:id]) line tells Rails to find only the book that has the id defined in params[:id].

The params object is a container that enables you to pass values between method calls. For example, when you're on the page called by the list method, you can click a link for a specific book, and it passes the id of that book via the params object so that show can find the specific book.

Implementing the index Method

The index method gives you a list of all the books in the database. This functionality will be achieved by the following lines of code. Edit the following lines in book_controller.rb file.

defindex@books=Book.all
render json:@booksend</pre>

The books_controller.rb file has the code as follows −

classBooksController<ApplicationControllerdefindex@books=Book.all
render json:@booksenddefshow@book=Book.find(params[:id])
render json:@bookenddefcreate@book=Book.new(book_params)[email protected]
  render json:@book, status::createdelse
  render json:@book.errors, status::unprocessable_entityendendprivatedefbook_params
params.require(:book).permit(:title,:author,:price)endend</pre>

Note that the book_params method defined above is a private method in the controller that ensures only the allowed attributes of a Book record are accepted from user input. It prevents mass assignment vulnerabilities, which could allow a user to update fields they shouldn’t have access to.

Rails also generates config/routes.rb file. Modify it to define RESTful routes:

Rails.application.routes.draw do
  resources :booksend

You will learn more about routes in Rails in one of the subsequent chapters.

Test the Controller

To verify if the actions defined in BooksController work as desired, start your Rails server:

rails server

Use the Postman tool to test endpoints of your application:

POST http://localhost:3000/books → to create a new book

Set the Content-Type header application/json and enter the following JSON expression as body:

{"book":{"title":"FUNDAMENTALS OF COMPUTERS","author":"Rajaraman","price":475}}

Execute the POST action. This adds a new record in the books table:

GET/books/:1 → Fetch a specific book with id=1

Postman's response pane will display the details of specified book:

GET/books → list all the books in the model 

The responses pane displays the JSON representation of all the books available.

You can also implement the UPDATE and DELETE operations in the BooksController by adding these action methods.

defupdate@book=Book.find(params[:id])[email protected](book_params)
  render json:@bookelse
  render json:@book.errors, status::unprocessable_entityendenddefdestroy@book=Book.find(params[:id])@book.destroy
head :no_contentend</pre>

What is Next?

You have created almost all the methods, which will work on backend. Next we will define routes (URLs) for actions.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *