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

时光怂恿深爱的人放手 提交于 2019-12-03 02:10:48

问题


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?


回答1:


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



回答2:


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



回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/2634964/how-to-add-a-custom-restful-route-to-a-rails-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!