Nested and non-nested resources, and admin restrictions

This is a fairly long question, but it’s a common one that applies to
a lot of applications. Here goes!

Many apps have/want a setup similar to this:

  1. ModelA has many ModelBs (Eg: User has many Photos).
  2. Admins CRUD all photos at /photos and beyond (Eg: /photos/1/edit).
  3. Admins CRUD User photos at /user/1/photos and beyond.
  4. Users CRUD their photos at /account/photos and beyond.

Some people don’t bother with #2, because photos can be CRUDed via #3.
However, I want #2 because it gives you a higher/broader view of the
Photos resource.

I’m trying to figure out an efficient, DRY/semi-DRY way of
implementing this. At the moment:

For #2 above, I’ve:

  1. Restricted PhotosController to admins.
  2. Created a Photos resource (map.resources :photos).

For #3 above, I’ve:

  1. Nested a Photos resource within the Users resource:
    map.resources :users, :has_many => :photos

For #4 above, I’ve:

  1. Created Account::PhotosController, which restricts photos to the
    current user (account).
  2. Nested Account::PhotosController within the Account singleton
    map.resource :account do |account|
    account.resources :photos, :controller => ‘account/photos’

Everything but #3 works perfectly. /user/1/photos calls
PhotosController#index , which finds all photos, rather than finding
only photos belonging to user 1.

I’ve come up with a few solutions, but don’t feel that any of them are

Solution #1:
Create a whole new controller, which finds photos within the specified
user. However, this would duplicate 95% of PropertiesController, which
is pretty dirty.

Solution #2:
Create a method in PhotosController that abstracts the finding of
photos. However, this feels wrong because it’s mixing functionality
between two different resources (photos vs user-photos).

Solution #3:
Create a new controller which inherits from PhotosController, and add
a bit of logic to PhotosController to prevent it from finding photos
when they’ve already been found.

Solution #4:
Use the resource_controller plugin. However, I find that r_c limits
what I can do in some controller actions. For example, r_c only
provides customisable failure scenarios for #create, #update and
#destroy, while I need to customise every action’s failure scenario.

So, what do you guys think of those solutions, and are there any other
solutions that are more ideal?


This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs