在Rails 3中路由嵌套资源

cor*_*ard 33 ruby routing ruby-on-rails ruby-on-rails-3

我有一个非常常见的嵌套路由的情况,我觉得,看起来像这样(在某种伪旋律):

'/:username/photos' => Show photos for User.find_by_username
'/photos' => Show photos for User.all
Run Code Online (Sandbox Code Playgroud)

简而言之:我有用户.他们有照片.我希望能够在他们的页面上显示他们的照片.我也希望能够显示所有照片,无论用户如何.我想保持我的路线RESTful,并使用内置resource方法感觉是正确的方式来做到这一点.


执行此操作的选项1是让PhotosController #index使用条件来检查给出了哪些参数并获取照片列表并设置视图(用户照片与所有照片不同).路由它甚至很容易:

resources :photos, :only => [:index]
scope ':/username' do
  resources :photos
end
Run Code Online (Sandbox Code Playgroud)

繁荣.它会看起来像Rails的是设置此.然而,在路线之后,事情变得更加复杂.在PhotosController #index动作中的条件变得越来越臃肿,并且正在进行大量的delgation.随着应用程序的增长以及我想要显示照片的方式的增加,它只会变得更糟.

选项2可能是让User :: PhotosController处理用户照片,以及一个PhotosController来处理显示所有照片.

resources :photos, :only => [:index]
namespace :user, :path => '/:username' do
  resources :photos
end
Run Code Online (Sandbox Code Playgroud)

这会产生以下路线:

           photos GET    /photos(.:format)                    {:action=>"index", :controller=>"photos"}
      user_photos GET    /:username/photos(.:format)          {:action=>"index", :controller=>"user/photos"}
                  POST   /:username/photos(.:format)          {:action=>"create", :controller=>"user/photos"}
   new_user_photo GET    /:username/photos/new(.:format)      {:action=>"new", :controller=>"user/photos"}
  edit_user_photo GET    /:username/photos/:id/edit(.:format) {:action=>"edit", :controller=>"user/photos"}
       user_photo GET    /:username/photos/:id(.:format)      {:action=>"show", :controller=>"user/photos"}
                  PUT    /:username/photos/:id(.:format)      {:action=>"update", :controller=>"user/photos"}
                  DELETE /:username/photos/:id(.:format)      {:action=>"destroy", :controller=>"user/photos"}
Run Code Online (Sandbox Code Playgroud)

我认为这很好用,但是一切都在User模块下,我觉得当我将它与其他东西集成时可能会导致问题.

问题

  • 有没有人有这样的经历?
  • 任何人都可以分享更好的处理方式吗?
  • 使用这些选项中的任何一个都可以考虑任何其他优缺点吗?

更新:我已经继续实施选项2,因为它让Rails的逻辑工作感觉更清晰,而不是覆盖它.到目前为止事情进展顺利,但我还需要将我的命名空间重命名为:users并添加一个:as => :user以防止它与我的User模型发生冲突.我还重写了模型to_param上的方法User以返回用户名.路径助手仍然以这种方式工作.

我仍然很感激这种方法的反馈.我是按照预期的方式做事,还是我滥用这个功能?

Mat*_*ght 7

在这种情况下,您是否考虑过使用浅层嵌套路由?

浅路嵌套有时,嵌套资源会产生繁琐的URL.解决方法是使用浅路由嵌套:

resources :products, :shallow => true do
  resources :reviews
end
Run Code Online (Sandbox Code Playgroud)

这样可以识别以下路线:

/products/1 => product_path(1)
/products/1/reviews => product_reviews_index_path(1)
/reviews/2 => reviews_path(2)
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的警告,但我一直在非Rails应用程序中使用它们多年来没有问题.不做虚荣网址并不是真的可以接受; Facebook甚至屈服于这种需求. (2认同)

cor*_*ard 6

执行此操作的最佳方式取决于应用程序,但在我的情况下,它肯定是选项B.使用命名空间路由我能够使用模块以非常干净的方式将不同的关注点分离到不同的控制器中.我还使用特定于命名空间的控制器向特定命名空间中的所有控制器添加共享功能(例如,添加before_filter以检查命名空间中所有资源的身份验证和权限).

  • 如果你能提供一个这样的代码示例,那就太好了!(即使它只是复制和粘贴上面的选项并添加一些示例控制器代码) (11认同)