I have two classes:
class User < ActiveRecord::Base
:has_one :foo
end
class Foo < ActiveRecord::Base
:belongs_to :user
end
The Foo is optional.
I created the following rout开发者_开发百科ing:
resources :users do
resources :foo
end
Which results in the following routes:
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"}
Questions:
- It seems like the Index and Show actions are redundant. Should one of them be removed? If so, which one?
- The :id parameter in the Show action seems unnecessary, as user_id is a foreign key in the foos table and there is only one foo per user. Am I mistaken?
- I would like to have a graceful way to route to the New action if there isn't a foo. One option would be to test @user.foo.nil? in the FooController's Show or Index action, then redirect to the New action. Is there a better way?
Thanks for your time.
If your model has a has_one association, try to set up the route using resource :foo
(note the singular method name "resource", not "resources"). This will set up a singleton resource route (which e.g. has no index action and member actions don't have an id param since there's only one member). See also http://apidock.com/rails/ActionController/Resources/resource (2.3 documentation, but applies to 3.0 as well afaik).
I can understand why Craig missed that actually. It's such a subtle difference it didn't even cross my mind. The only thing that tipped me off is that my named routes for the singleton resource has a weird index name: user_foo_index
instead of user_foos
.
It's a really smart deduction from the absence of plural on the part of Rails.
Warning: The following examples use shallow nesting by either doing this:
resources :cats, shallow: true do
resources :noms
end
Or that:
resources :cats do
shallow do
resources :noms
end
end
Anyway back to business, if you setup a singular resource – address
as opposed to articles
for instance – and you see something like this:
user_address_index GET | POST
new_user_address GET
edit_address GET
address GET | PUT | DELETE
Then as Andreas justly pointed out, you probably incorrectly declared this in your routes:
resources :users do
resources :address
end
And if you change that to:
resources :users do
resource :address
end
You should be all fine and happy and see something like this if you punch rake routes
in your prompt:
user_address POST | GET | PUT | DELETE
new_user_address GET
edit_user_address GET
Note: I know the output of rakes routes doesn't look exactly like this (it's a lot more verbose), I'm just simplifying for the sake of focus.
Hope that helps.
精彩评论