2010-07-27 130 views
10

我有两个类:的Rails 3 HAS_ONE路由

class User < ActiveRecord::Base 
    :has_one :foo 
end 

class Foo < ActiveRecord::Base 
    :belongs_to :user 
end 

foo的是可选的。

我创建了以下路由:

resources :users do 
    resources :foo 
end 

导致以下路线:

GET /users/:user_id/foo(.:format)    {:controller=>"foos", :action=>"index"} 
user_foos POST /users/:user_id/foo(.:format)    {:controller=>"foos", :action=>"create"} 
new_user_foo GET /users/:user_id/foo/new(.:format)   {:controller=>"foos", :action=>"new"} 
GET /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"show"} 
PUT /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"update"} 
user_foo DELETE /users/:user_id/foo/:id(.:format)   {:controller=>"foos", :action=>"destroy"} 
edit_user_foo GET /users/:user_id/foo/:id/edit(.:format)  {:controller=>"foos", :action=>"edit"} 

问题:

  1. 好像索引和显示的动作是多余的。如果其中一个被删除?如果是这样,哪一个?
  2. Show操作中的id参数看起来没有必要,因为user_id是foos表中的外键,每个用户只有一个foo。我错了吗?
  3. 如果没有foo,我希望能有一种优雅的方式来路由到New动作。一种选择是测试@ user.foo.nil?在FooController的显示或索引操作中,然后重定向到新操作。有没有更好的办法?

谢谢你的时间。

回答

25

如果您的模型具有has_one关联,请尝试使用resource :foo(请注意单数方法名称“resource”,而不是“resources”)设置路径。这将设置一个单例资源路由(例如没有索引操作,并且由于只有一个成员,所以成员操作没有id参数)。另见http://apidock.com/rails/ActionController/Resources/resource(2.3文档,但适用于3.0以及afaik)。

+2

不能相信我错过了。 – craig 2010-08-03 12:51:03

+1

感谢您的信息 – 2013-10-09 12:27:24

2

我可以理解为什么克雷格实际上错过了。它是如此微妙的差异,它甚至没有跨过我的脑海。唯一让我失望的是我的单身资源的命名路线有一个奇怪的索引名称:user_foo_index而不是user_foos

这是一个从Rails的复数的缺席真正聪明的演绎。

警告:下面的示例通过两种这样使用浅嵌套

resources :cats, shallow: true do 
    resources :noms 
end 

或者说:

resources :cats do 
    shallow do 
    resources :noms 
    end 
end 

反正回到企业,如果你设置一个单一的资源 - address而不是articles例如 - 你看到这样的事情:

user_address_index GET | POST 
    new_user_address GET 
     edit_address GET 
      address GET | PUT | DELETE 

然后如安德烈亚斯公正地指出的那样,你可能不正确地在你的路由宣告此:

resources :users do 
    resources :address 
end 

如果把它修改成:

resources :users do 
    resource :address 
end 

你应该都很好,很快乐并看到类似的东西,如果你在你的提示中打出rake routes

 user_address POST | GET | PUT | DELETE 
new_user_address GET 
edit_user_address GET 

注意:我知道rake路由的输出看起来不像这样(它更加冗长),我只是为了关注而简化。

希望有所帮助。