[英]Routing nested resources in Rails 3
我有一個非常常見的嵌套路由的情況,我覺得,看起來像這樣(在某種偽旋律):
'/:username/photos' => Show photos for User.find_by_username
'/photos' => Show photos for User.all
簡而言之:我有用戶。 他們有照片。 我希望能夠在他們的頁面上顯示他們的照片。 我也希望能夠顯示所有照片,無論用戶如何。 我想保持我的路由RESTful,並使用內置的resource
方法感覺是正確的方法。
執行此操作的選項1是讓PhotosController #index使用條件來檢查給出了哪些參數並獲取照片列表並設置視圖(用戶照片與所有照片不同)。 路由它甚至很容易:
resources :photos, :only => [:index]
scope ':/username' do
resources :photos
end
繁榮。 看起來 Rails就是這樣設置的。 然而,在路線之后,事情變得更加復雜。 在PhotosController #index動作中的條件變得越來越臃腫,並且正在進行大量的delgation。 隨着應用程序的增長以及我想要顯示照片的方式的增加,它只會變得更糟。
選項2可能是讓User :: PhotosController處理用戶照片,以及一個PhotosController來處理顯示所有照片。
resources :photos, :only => [:index]
namespace :user, :path => '/:username' do
resources :photos
end
這會產生以下路線:
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"}
我認為這很好用,但是一切都在User模塊下,我覺得當我將它與其他東西集成時可能會導致問題。
更新 :我已經繼續實施選項2,因為它讓Rails的邏輯工作感覺更清晰,而不是覆蓋它。 到目前為止事情進展順利,但我還需要將我的命名空間重命名為:users
並添加:as => :user
以防止它與我的User
模型發生沖突。 我還重寫了User
模型上的to_param
方法以返回用戶名。 路徑助手仍然以這種方式工作。
我仍然很感激這種方法的反饋。 我是按照預期的方式做事,還是我誤用了這個功能?
在這種情況下,您是否考慮過使用淺層嵌套路由?
淺路嵌套有時,嵌套資源會產生繁瑣的URL。 解決方法是使用淺路由嵌套:
resources :products, :shallow => true do
resources :reviews
end
這樣可以識別以下路線:
/products/1 => product_path(1)
/products/1/reviews => product_reviews_index_path(1)
/reviews/2 => reviews_path(2)
執行此操作的最佳方式取決於應用程序,但在我的情況下,它肯定是選項B.使用命名空間路由我能夠使用模塊以非常干凈的方式將不同的關注點分離到不同的控制器中。 我還使用特定於命名空間的控制器向特定命名空間中的所有控制器添加共享功能(例如,添加before_filter以檢查命名空間中所有資源的身份驗證和權限)。
我在我的一個應用程序中做了類似的事情。 你走在正確的軌道上。 我所做的是聲明嵌套資源,並使用Rails 3中Active Record的靈活的基於arel的語法構建查詢。在您的情況下,它可能看起來像這樣:
# config/routes.rb
resources :photos, :only => :index
resources :users do
resources :photos
end
# app/controllers/photos_controller.rb
def index
@photos = Photo.scoped
@photos = @photos.by_user(params[:user_id]) if params[:user_id]
# ...
end
您可以為一個用戶定義一個單獨的路徑來獲取照片,如下所示:
get '(:username)/photos', :to => 'photos#index'
但我建議只使用Jimmy上面發布的嵌套資源,因為這是最靈活的解決方案。
Example::Application.routes.draw do
resources :accounts, :path => '' do
resources :projects, :path => '', :except => [:index]
end
end
得到了這樣的例子: http : //jasoncodes.com/posts/rails-3-nested-resource-slugs
剛剛在我當前的項目中應用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.