11

我有两节课:

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. 似乎 Index 和 Show 操作是多余的。应该删除其中一个吗?如果有,是哪一个?
  2. Show 操作中的 :id 参数似乎没有必要,因为 user_id 是 foos 表中的外键,每个用户只有一个 foo。我弄错了吗?
  3. 如果没有 foo,我希望有一种优雅的方式来路由到 New 操作。一种选择是测试@user.foo.nil?在 FooController 的 Show 或 Index 操作中,然后重定向到 New 操作。有没有更好的办法?

谢谢你的时间。

4

2 回答 2

28

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

于 2010-08-02T14:59:21.223 回答
3

我可以理解为什么克雷格实际上错过了这一点。这是一个如此微妙的差异,我什至没有想到。唯一让我知道的是,我为单例资源命名的路由有一个奇怪的索引名称: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

然后正如 Andreas 正确指出的那样,您可能在路线中错误地声明了这一点:

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 路由的输出看起来并不完全像这样(它更冗长),我只是为了集中注意力而进行简化。

希望有帮助。

于 2011-08-30T16:13:16.067 回答