【问题标题】:How to add a custom RESTful route to a Rails app?如何将自定义 RESTful 路由添加到 Rails 应用程序?
【发布时间】:2011-02-07 18:18:44
【问题描述】:

我正在读这两页

  1. resources
  2. Adding more RESTful actions

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 路由指南中所述)。

有什么帮助吗?

【问题讨论】:

    标签: ruby-on-rails rest routing


    【解决方案1】:

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

    show
    index
    new
    create
    edit
    update
    destroy
    

    这些操作可以分为两组:

    • :member 操作

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

    users/1/edit 
    users/1
    

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

    默认成员操作:showeditupdatedestroy

    • :collection 操作

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

    users/login
    users/register
    

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

    默认收集操作:indexnewcreate

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

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

    动作的网址如下:

    users/signup
    users/register
    

    如果您想删除 Rails 生成的标准操作,请使用 :except/:only 选项:

    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
    

    【讨论】:

    • @KandadaBoggu,这个解释看起来很棒。作为后续检查我的理解,假设我想在用户的欢迎电子邮件中发送“帐户确认”链接。该链接将包含一个 8 个字符的验证哈希。我要添加map.resources :users, :member =&gt; {:validate =&gt; :get} 吗? hash 参数如何插入?
    • 更新了我的答案,看看吧。
    • 什么告诉confirm_user_path 使用@user.confirmation_code 代替:id 通配符而不是@user.foo@user.bar?这应该是confirm_user_path(:id =&gt; @user.confirmation_code)吗?
    • @KandadaBoggu,请注意:StackOverflow 说我可以在 4 小时内发放赏金 :)
    • 是的,你必须使用confirm_user_path(:id =&gt; @user.confirmation_code),我会更新答案。
    【解决方案2】:

    这可以看作是另一种语法——可能是一些值得了解的东西。

    语法 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 的答案就是您要走的路。

    【讨论】:

    • @mikezter,我肯定还需要newcreate 路线。但是,这回答了我对过去的重命名路线的疑问。谢谢:)
    【解决方案4】:

    new 选项允许您创建用于创建新对象的新路由。这就是为什么它们以该术语为前缀。

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

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

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

    【讨论】:

    • 我很难理解collection 的用途。 is 路径用于创建新对象;注册的访问者创建一个新的User 对象。那么,我为什么不想使用new?这是 Rails 指南中的错字吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多