Note that there are some explanatory texts on larger screens.

plurals
  1. PORouting nested resources in Rails 3
    primarykey
    data
    text
    <p>I have a pretty common case for nested routes, I feel like, that looks something like this (in some sort of pseudonotation):</p> <pre><code>'/:username/photos' =&gt; Show photos for User.find_by_username '/photos' =&gt; Show photos for User.all </code></pre> <p><strong>In a nutshell:</strong> I have users. They have photos. I want to be able to show their photos on their page. I also want to be able to show all photos, regardless of the user. I'd like to keep my routes RESTful and using the built-in <code>resource</code> methods feels like the right way to do it.</p> <hr> <p><strong>Option 1</strong> for doing this is to have PhotosController#index use a conditional to check which params are given and get the list of photos and set the view (different for a user's photos than for all photos). It's even easy to route it:</p> <pre><code>resources :photos, :only =&gt; [:index] scope ':/username' do resources :photos end </code></pre> <p>Boom. It'd <em>seem</em> like Rails was setup for this. After the routes, though, things get more complicated. That conditional back in the PhotosController#index action is just getting more and more bloated and is doing an awful lot of delgation. As the application grows and so do the number of ways I want to show photos, it is only going to get worse.</p> <p><strong>Option 2</strong> might be to have a User::PhotosController to handle user photos, and a PhotosController to handle showing all photos.</p> <pre><code>resources :photos, :only =&gt; [:index] namespace :user, :path =&gt; '/:username' do resources :photos end </code></pre> <p>That generates the following routes:</p> <pre><code> photos GET /photos(.:format) {:action=&gt;"index", :controller=&gt;"photos"} user_photos GET /:username/photos(.:format) {:action=&gt;"index", :controller=&gt;"user/photos"} POST /:username/photos(.:format) {:action=&gt;"create", :controller=&gt;"user/photos"} new_user_photo GET /:username/photos/new(.:format) {:action=&gt;"new", :controller=&gt;"user/photos"} edit_user_photo GET /:username/photos/:id/edit(.:format) {:action=&gt;"edit", :controller=&gt;"user/photos"} user_photo GET /:username/photos/:id(.:format) {:action=&gt;"show", :controller=&gt;"user/photos"} PUT /:username/photos/:id(.:format) {:action=&gt;"update", :controller=&gt;"user/photos"} DELETE /:username/photos/:id(.:format) {:action=&gt;"destroy", :controller=&gt;"user/photos"} </code></pre> <p>This works pretty well, I think, but everything is under a User module and I feel like that might end up causing problems when I integrate it with other things.</p> <h3>Questions</h3> <ul> <li>Does anybody have experience with something like this?</li> <li>Can anybody share a better way of handling this?</li> <li>Any additional pros and cons to consider with either of these options?</li> </ul> <hr> <p><strong>Update</strong>: I've gone ahead implementing Option 2 because it feels cleaner allowing Rails' logic to work rather than overriding it. So far things are going well, but I also needed to rename my namespace to <code>:users</code> and add an <code>:as =&gt; :user</code> to keep it from clashing with my <code>User</code> model. I've also overridden the <code>to_param</code> method on the <code>User</code> model to return the username. Path helpers still work this way, too.</p> <p><em>I'd still appreciate feedback on this method. Am I doing things the expected way, or am I misusing this functionality?</em></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload