Custom REST Actions in Rails 5


Step 1

There are 7 standard actions provided by resources declaration in the routes.rb.

resources :tasks

Step 2

The index page displays all the tasks. For completed tasks, define a completed method:

def completed
  @tasks = Task.where(complete: false)  

This finds all the completed tasks.

Step 3

Go to complete view in the browser http://localhost:3000/completed. It will not work. Delete this:

before_action :set_task, only: [:show, :edit, :update, :destroy]

Try again. The error is:

ActiveRecord::RecordNotFound in TasksController#show
Couldn't find Task with 'id'=completed

Step 4

Change the routes.rb to allow complete action for task resource.

get 'completed', to: 'tasks#completed', as: :completed_tasks

Step 5

$ rake routes | grep tasks

The installed routes are:

          tasks GET    /tasks(.:format)             tasks#index
                POST   /tasks(.:format)             tasks#create
       new_task GET    /tasks/new(.:format)         tasks#new
      edit_task GET    /tasks/:id/edit(.:format)    tasks#edit
           task GET    /tasks/:id(.:format)         tasks#show
                PATCH  /tasks/:id(.:format)         tasks#update
                PUT    /tasks/:id(.:format)         tasks#update
                DELETE /tasks/:id(.:format)         tasks#destroy
completed_tasks GET    /completed(.:format)         tasks#completed

Step 6

Go to completed view in the browser by browsing to http://localhost:3000/completed. In the log file, you can see that nothing was rendered.

Started GET "/completed" for ::1 at 2016-03-23 17:47:54 -0700
Processing by TasksController#completed as HTML
No template found for TasksController#completed, rendering head :no_content
  Task Load (0.1ms)  SELECT "tasks".* FROM "tasks" WHERE "tasks"."complete" = ?  [["complete", true]]
Completed 204 No Content in 20ms (ActiveRecord: 0.1ms)

Step 7

Define completed.html.erb:

<h1>Completed Tasks</h1>


      <% for task in @tasks %>
        <div class='task'>
            <strong> <%= %> </strong>
        <%= link_to 'Edit', edit_task_path(task) %>
      <% end %>

Step 8

Add a link to completed tasks in the index page.

<%= link_to "Completed Tasks", completed_tasks_path %>

Step 9

Implement the complete action:

def complete
  @task = Task.find(params[:id])  
  @task.update_attribute(:complete, true)
  flash[:notice] = 'marked task as complete'

  redirect_to completed_tasks_path

Step 10

Define the routes for marking a task as complete.

put 'complete/:id', to: 'tasks#complete', as: :complete_task

Step 11

Add the link to mark a task as complete in index page:

<%= link_to 'Mark as Complete', complete_task_path(task), method: :put %>

Step 12

Browse to http://localhost:3000/tasks. Click on 'Mark as Complete' to mark a task as complete. It shows up in completed tasks page


In this article, you learned how to use custom REST actions in Rails 5.

Related Articles

Create your own user feedback survey