1

I have a Problem with Nested Resources.

2 Models

User => has_many :stuffs

Stuff => belongs_to :user

routes.rb

map.resources :stuffs

map.resources :users, :has_many => [:stuffs]

When i call /users/1/stuffs it presents me the Stuff for the corresponding User. but i got this also when i call /users/2/stuffs. It should return 0 "Stuffs" but it dont work.

MySQL Query from Server
SELECT * FROM `stuffs`

rake routes

stuffs GET    /stuffs(.:format)                         {:action=>"index", :controller=>"stuffs"}
                POST   /stuffs(.:format)                         {:action=>"create", :controller=>"stuffs"}
      new_stuff GET    /stuffs/new(.:format)                     {:action=>"new", :controller=>"stuffs"}
     edit_stuff GET    /stuffs/:id/edit(.:format)                {:action=>"edit", :controller=>"stuffs"}
          stuff GET    /stuffs/:id(.:format)                     {:action=>"show", :controller=>"stuffs"}
                PUT    /stuffs/:id(.:format)                     {:action=>"update", :controller=>"stuffs"}
                DELETE /stuffs/:id(.:format)                     {:action=>"destroy", :controller=>"stuffs"}
    user_stuffs GET    /users/:user_id/stuffs(.:format)          {:action=>"index", :controller=>"stuffs"}
                POST   /users/:user_id/stuffs(.:format)          {:action=>"create", :controller=>"stuffs"}
 new_user_stuff GET    /users/:user_id/stuffs/new(.:format)      {:action=>"new", :controller=>"stuffs"}
edit_user_stuff GET    /users/:user_id/stuffs/:id/edit(.:format) {:action=>"edit", :controller=>"stuffs"}
     user_stuff GET    /users/:user_id/stuffs/:id(.:format)      {:action=>"show", :controller=>"stuffs"}
                PUT    /users/:user_id/stuffs/:id(.:format)      {:action=>"update", :controller=>"stuffs"}
                DELETE /users/:user_id/stuffs/:id(.:format)      {:action=>"destroy", :controller=>"stuffs"}
          users GET    /users(.:format)                          {:action=>"index", :controller=>"users"}
                POST   /users(.:format)                          {:action=>"create", :controller=>"users"}
       new_user GET    /users/new(.:format)                      {:action=>"new", :controller=>"users"}
      edit_user GET    /users/:id/edit(.:format)                 {:action=>"edit", :controller=>"users"}
           user GET    /users/:id(.:format)                      {:action=>"show", :controller=>"users"}
                PUT    /users/:id(.:format)                      {:action=>"update", :controller=>"users"}
                DELETE /users/:id(.:format)                      {:action=>"destroy", :controller=>"users"}
           root        /                                         {:action=>"index", :controller=>"users"}

gem list

actionmailer (2.3.8)
actionpack (2.3.8)
activerecord (2.3.8)
activeresource (2.3.8)
activesupport (2.3.8)
arel (2.0.6)
authlogic (2.1.6)
builder (2.1.2)
cgi_multipart_eof_fix (2.5.0)
gem_plugin (0.2.3)
i18n (0.5.0)
mongrel (1.1.5 x86-mingw32)
mysql (2.8.1 x86-mingw32)
paperclip (2.3.7)
rack (1.1.0)
rails (2.3.8)
rake (0.8.7)
tzinfo (0.3.23)

There is no where clause for the corresponding user_id. But how to fix it?

Rails Version 2.3.8

Should work like this => http://guides.rubyonrails.org/routing.html 2.7 Nested Resources

Hope somebody can help

Nihil
  • 23
  • 5

4 Answers4

5

In your Stuffs controller's index method, how are you collecting your stuffs? If you used a scaffold to create the controller it will default to something like

@stuffs = Stuff.all

but should be something along the lines of

@user = User.find(params[:user_id])
@stuffs = @user.stuffs

or something to that effect--basically, you're collecting the user's stuff, not all stuff.

Aaron Sumner
  • 226
  • 1
  • 3
  • Hm, i could do that, but i thought rails takes this part, when i add the :has_many relationship in routes.rb. I Also want to call /stuffs/ With your Code it will throw an error :( – Nihil Dec 14 '10 at 16:41
  • 1
    If you want to list all Stuff on /stuffs/ and a user's Stuff on /user/:user_id/stuffs, you'll have to check for the user_id parameter. Essentially, if params[:user_id] is set, use the code that gets the user's stuff, otherwise get everything. – Dominic Dec 14 '10 at 16:58
  • I thought rails autmaticlly handles that. Like here => http://railscasts.com/episodes/139-nested-resources – Nihil Dec 14 '10 at 17:11
  • 1
    @Nihil if you follow the link to the full source code you can see where he loads the filtered collection: https://github.com/ryanb/railscasts-episodes/blob/master/episode-139/blog/app/controllers/comments_controller.rb – DGM Dec 15 '10 at 18:39
3

Rails controllers will not filter your results by default. As above, since you're probably calling Stuff.all in your StuffsController, it will always return all Stuff objects.

I use inherited_resources for the default behaviour on my sites. It handles these relationships automatically and lets you override it when you want different behaviour:

https://github.com/josevalim/inherited_resources

Dominic
  • 3,304
  • 19
  • 22
0

Routes alone don't affect the model. Since the user id is passed in, though, you can do:

User.find(params[:user_id]).stuffs
DGM
  • 26,629
  • 7
  • 58
  • 79
  • Hm, but it should work, thats the problem :( See also: http://guides.rubyonrails.org/routing.html 2.7 Nested Resources – Nihil Dec 14 '10 at 16:50
  • No, that only affects the url routing. When you get the collection of objects, you still have to filter it by the nested id yourself. That guide makes no claim otherwise. – DGM Dec 15 '10 at 18:37
0

Try this

map.resources :users do |users|
  users.resources :stuffs
end
codevoice
  • 474
  • 3
  • 6