如何将自定义RESTful路由添加到Rails应用程序?

时间:2010-04-14 04:48:28

标签: ruby-on-rails rest routing

我正在读这两页

  1. resources
  2. Adding more RESTful actions
  3. Rails指南页面显示

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

    及其相应的网址

    /photos/upload
    

    这看起来很棒。


    我的routes.rb显示了这个

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

    当我这样做时:[~/my_app]$ rake routes

    我看到添加了两条新路线

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

    注意包含/new!我想要那个。我只想要/users/signup/users/register(如Rails路由指南中所述)。

    任何帮助?

4 个答案:

答案 0 :(得分:61)

将控制器公开为资源时,会自动添加以下操作:

show
index
new
create
edit
update
destroy

这些操作可以分为两组:

  • :member行动

成员操作的URL具有目标资源的ID。例如:

users/1/edit 
users/1

您可以将:member操作视为类的实例方法。它始终适用于现有资源。

默认会员操作:showeditupdatedestroy

  • :collection行动

:collection操作的网址不包含目标资源的ID。例如:

users/login
users/register

您可以将:collection操作视为类的静态方法。

默认收集操作:indexnewcreate

在您的情况下,您需要两个新的注册操作。这些操作属于:集合类型(因为您在提交这些操作时没有用户的ID)。您的路线如下:

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

操作的URL如下:

users/signup
users/register

如果要删除Rails生成的标准操作,请使用:除/:only options:

map.resources :foo, :only => :show

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

修改1

我通常将confirmation操作视为:member操作。在这种情况下,params[id]将包含确认码。

路线配置:

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

<强>网址

/users/xab3454a/confirm

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

<强>控制器

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

答案 1 :(得分:12)

这可以作为另一种语法 - 有些可能很有用。

语法1:

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

Rake Route输出将包括

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

RS“}

语法2: 如果您只有一个收集路线

resources :users do
    get 'signup', :on => :collection
end

答案 2 :(得分:3)

如果我正确理解您的问题,您只需要重命名newcreate操作的网址。

这样做会这样做:

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

如果您真的想要添加新路由以及相应的控制器操作,那么Damiens的回答是可行的方法。

答案 3 :(得分:1)

new选项允许您创建用于创建新对象的新路径。这就是他们以该术语为前缀的原因。

您正在寻找的是:collection选项。

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

这将创建/users/signup/users/register网址。