# Rails Tutorial: Create Todo Controller

Generate a Todo controller

Generating a controller is easy. Just run the following command:

bin/rails generate controller Todos

You should see an output similar to the following (ignore the Deprecation warning):

   create  app/controllers/todos_controller.rb
   invoke  erb
   create    app/views/todos
   invoke  test_unit
identical    test/controllers/todos_controller_test.rb
   invoke  helper
identical    app/helpers/todos_helper.rb
   invoke    test_unit
   invoke  assets
   invoke    coffee
   invoke    scss

Replace your rails-todolist/app/controllers/todos_controller.rb with the following code:


class TodosController < ApplicationController
  def index
    @todos = Todo.all

    if request.xhr?
      render :json => { todos: @todos }
    else
      renderHTML todos: @todos
    end
  end

  def show
    @todo = Todo.find(params[:id])

    if request.xhr?
      render :json => { todo: @todo }
    else
      renderHTML todo: @todo
    end
  end

  def create
    @todo = Todo.new(:todo => params[:todo],
                     :completed => parse_boolean(params[:completed]))
    if @todo.save
      render :json => { todo: @todo }
    else
      render :json => { errors: @todo.errors }
    end
  end

  def update
    @todo = Todo.find(params[:id])

    if @todo.update(todo_params)
      render :json => { todo: @todo }
    else
      render :json => { errors: @todo.errors }
    end
  end

  def destroy
    @todo = Todo.find(params[:id])
    @todo.destroy

    render :json => { todo: @todo }
  end

  private
    def parse_boolean(param)
      ActiveRecord::Type::Boolean.new.deserialize(param)
    end

    def todo_params
      params.permit(:todo, :completed)
    end
end

The above controller code is pretty self-explanatory. We define 5 actions index, show, create, update and destroy which create, read, update or delete Todo items and respond back with JSON data. However, of these routes, the index and show actions are special. We check if the incoming request is an XMLHttpRequest (AJAX) or not and render accordingly. We provide a renderHTML helper that will take the data supplied and render the React component corresponding to that route on the server-side. How does it know which route to render? We use the same route paths defined server-side on the client as well (defined as Route's to react-router). This is explained in the next section of the tutorial.

For want of simplicity, assume for now that renderHTML knows how to pick the correct React view component and render HTML accordingly.

Define a resource for the TodoController

Open rails-todolist/config/routes.rb in your favorite editor and make the following changes:


Rails.application.routes.draw do
  resources :todos

  root 'todos#index'
  # root 'welcome#index'
end

We define a todos resource and set the root to todos#index. We comment out the default welcome#index route.

To see how these routes are defined, run the following command:

$ bin/rails routes

You should see an output similar to the following (ignore the Deprecation warning):

   Prefix Verb   URI Pattern               Controller#Action
    todos GET    /todos(.:format)          todos#index
          POST   /todos(.:format)          todos#create
 new_todo GET    /todos/new(.:format)      todos#new
edit_todo GET    /todos/:id/edit(.:format) todos#edit
     todo GET    /todos/:id(.:format)      todos#show
          PATCH  /todos/:id(.:format)      todos#update
          PUT    /todos/:id(.:format)      todos#update
          DELETE /todos/:id(.:format)      todos#destroy
     root GET    /                         todos#index