Custom REST Actions in Rails 5
There are 7 standard actions provided by resources declaration in the routes.rb.
The index page displays all the tasks. For completed tasks, define a completed method:
def completed @tasks = Task.where(complete: false) end
This finds all the completed tasks.
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
Change the routes.rb to allow complete action for task resource.
get 'completed', to: 'tasks#completed', as: :completed_tasks
$ 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
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)
<h1>Completed Tasks</h1> <table> <thead> <tr> <th></th> </tr> </thead> <tbody> <tr> <% for task in @tasks %> <div class='task'> <strong> <%= task.name %> </strong> </div> <%= link_to 'Edit', edit_task_path(task) %> <% end %> </tr> </tbody> </table>
Add a link to completed tasks in the index page.
<%= link_to "Completed Tasks", completed_tasks_path %>
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 end
Define the routes for marking a task as complete.
put 'complete/:id', to: 'tasks#complete', as: :complete_task
Add the link to mark a task as complete in index page:
<%= link_to 'Mark as Complete', complete_task_path(task), method: :put %>
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.