2

I'm working on an app where users can share photos. The photos can optionally belong to a collection, but don't have to.

Currently users can look through all photos via: photos/id. I think it would also make sense if they could browse through the photos for a particular collection through collections/id/photos

So, this would mean that photos were both a top level resource and a nested resource. I suppose I could set this up in the routes like so:

resources :photos
resources :collections do
  resources :photos
end

Is this a good idea, or is there a better way to reuse the photo model while also allowing it to act as nested under collections when appropriate? I'd very much appreciate suggestions as to the "rails way" of handling this kind of scenario.

Thanks!

Andrew
  • 42,517
  • 51
  • 181
  • 281

1 Answers1

1

The routes you've suggested work perfectly fine. You do need to watch out in your Photos controller actions, though. Because they can be called for an individual photo OR a collection, you need to conditionally find photos based on what params are available.

Also, I'd suggest being more specific about which actions are available for each route:

resources :photos
resources :collections do
  resources :photos, :only => [:index, :create, :destroy]
end

# index => show photos in a collection
# create => add a photo to a collection
# destroy => remove a photo from a collection

You don't really need to be able to edit/update/show a photo as a member of a collection from the information you provided.

Another option is to use a namespaced route:

namespace :collection, :path => '/collection', :as => :collection do
  resources :photos, :only => [:index, :create, :destroy]
end

That will allow you to separate your Collection::Photos from your Photos…

controllers/photos_controller.rb
controllers/collections/photos_controller.rb

And if you really want, Rails lets you do the same to your views. Another benefit of using the namespace is that it sets up some really nifty route helpers:

photo_path(@photo) #=> /photos/1
collection_photos_path #=> /collections/1/photos
etc.
coreyward
  • 77,547
  • 20
  • 137
  • 166
  • Ah, that's a good point about the controller actions. I don't have major differences planned for browsing through photos in a collection or outside of a collection -- but I might change that in the future. Would it be simpler (more future-proof) to just define a `collections_photos` controller? – Andrew Feb 28 '11 at 23:54
  • @Andrew If you want to go with separating them out, you can use a namespace. I'll update right now with an example… – coreyward Mar 01 '11 at 00:04
  • Wow. The namespaces example is REALLY cool. I had never even heard of using namespaces in routes. Thank you very much, I'll check this option out. – Andrew Mar 01 '11 at 00:13
  • @Andrew Check out the docs for it (http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing). Also, I might have been a little overzealous; apparently using just `namespace 'collection' do` will perform similarly as above. – coreyward Mar 01 '11 at 00:30