2010-07-27 145 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路由的輸出看起來不像這樣(它更加冗長),我只是爲了關注而簡化。

希望有所幫助。