Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a custom RESTful route to a Rails app?

Tags:

I'm reading these two pages

  1. resources
  2. Adding more RESTful actions

The Rails Guides page shows

map.resources :photos, :new => { :upload => :post } 

And its corresponding URL

/photos/upload 

This looks wonderful.


My routes.rb shows this

map.resources :users, :new => { :signup => :get, :register => :post } 

When I do: [~/my_app]$ rake routes

I see the two new routes added

  signup_new_user GET    /users/new/signup(.:format) register_new_user POST   /users/new/register(.:format) 

Note the inclusion of /new! I don't want that. I just want /users/signup and /users/register (as described in the Rails Routing Guide).

Any help?

like image 252
maček Avatar asked Apr 14 '10 04:04

maček


People also ask

What are RESTful routes in Rails?

In Rails, a RESTful route provides a mapping between HTTP verbs, controller actions, and (implicitly) CRUD operations in a database. A single entry in the routing file, such as. map.resources :photos. creates seven different routes in your application: HTTP verb.

What are RESTful routes?

A RESTful route is a route that provides mapping from HTTP verbs (get, post, put, delete, patch) to controller CRUD actions (create, read, update, delete). Instead of relying solely on the URL to indicate what site to visit, a RESTful route depends on the HTTP verb and the URL.


2 Answers

When you expose a controller as a resource, following actions are automatically added:

show index new create edit update destroy 

These actions can be categorized in to two groups:

  • :member actions

The URL for the member action has the id of the target resource. E.g:

users/1/edit  users/1 

You can think of :member action as an instance method on a class. It always applies on an existing resource.

Default member actions: show, edit, update, destroy

  • :collection actions

The URL for the :collection action does not contain the id of the target resource. E.g:

users/login users/register 

You can think of :collection action as a static method on a class.

Default collection actions: index, new, create

In your case you need two new actions for registration. These actions belong to :collection type( as you do not have the id of the user while submitting these actions). Your route can be as follows:

map.resources :users, :collection => { :signup => :get, :register => :post } 

The URL for the actions are as follows:

users/signup users/register 

If you want to remove a standard action generated by Rails use :except/:only options:

map.resources :foo, :only => :show  map.resources :foo, :except => [:destroy, :show] 

Edit 1

I usually treat the confirmation action as a :member action. In this case params[id] will contain the confirmation code.

Route configuration:

map.resources :users, :member => { :confirm => :get} 

URL

/users/xab3454a/confirm  confirm_user_path(:id => @user.confirmation_code) # returns the URL above 

Controller

class UsersController < ApplicationController   def confirm     # assuming you have an attribute called `confirmation_code` in `users` table      # and you have added a uniq index on the column!!     if User.find_by_confirmation_code(params[id])       # success     else       # error     end   end end 
like image 180
Harish Shetty Avatar answered Oct 31 '22 21:10

Harish Shetty


This can be taken as just another syntax -- something good to know may be.

Syntax 1:

resources :users do   member do     get 'signup'     post 'register'   end end 

Rake Route Output will include

signup_users GET    /users/signup(.:format)    {:action=>"signup", :controller=>"users"} register_users POST   /users/register(.:format)  {:action=>"register", :controller=>"use 

rs"}

Syntax 2: If you have only one collection route

resources :users do     get 'signup', :on => :collection end 
like image 38
prashantsunkari Avatar answered Oct 31 '22 20:10

prashantsunkari