开发者

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

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 开发者_Go百科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?


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


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


If i'm understanding your question right, you just want to rename the urls of the new and create actions.

This would be done like so:

map.resources :users, :path_names => {:new => 'signup', :create => 'register'}

If you really would like to add new routes with corresponding controller actions, then Damiens answer is the way to go.


The new option allows you to create new routes for creating new objects. That's why they're prefixed with that term.

What you're looking for is the :collection option.

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

Which will create the /users/signup and /users/register urls.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜