2011-01-29 51 views
4

我有這個資源樹:嵌套資源 - 如何避免冗餘路由?

  • 論壇
    • 主題

我希望能夠獨立訪問它們儘可能。我想避免像/forum/:forum_id/topic/:topic_id/post/:id這樣的冗餘路由,因爲我只能做/post/:id

理想的路線是這樣的:

/forums => Forums#index    # Lists every forum 
/forum/new => Forums#new    # New forum 
/forum/edit => Forums#edit   # Edit forum 
/forum/:id => Forums#show   # Shows forum 
/forum/:id/forums Forums#index  # Lists nested forums 
/forum/:id/topics => Topics#index # Lists topics inside forum 
/forum/:id/topic/new => Topics#new # New topic 
/topics => Topics#index    # Lists every topic 
/topic/:id => Topics#show   # Shows topic 
/topic/:id/posts => Posts#index  # Lists posts inside topic 
/topic/:id/post/new => Posts#new  # New post 
/posts => Posts#index    # Lists every post 
/post/:id => Posts#show    # Shows post 

什麼對這樣的情況進行建模的最佳方式?

這裏是我的嘗試:

resources :forums 
resources :topics 
resources :posts 

resources :forums do 
    resources :topics 
end 

resources :topics do 
    resources :posts 
end 

的問題是,這些設置創造了很多無用的航線,如:

/forums/:forum_id/topic/:id # Redundant - /topic/:id 
/topics/:topic_id/post/:id # Redundant - /post/:id 
/topics/new     # No current forum 
/posts/new     # No current topic 

有什麼辦法來指定要創建哪些路線?

在控制器中,我該如何處理映射到同一動作的多個路由?例如,在Topics#index裏面我怎麼知道我是否應該處理GET /forum/:id/topicsGET /topics

回答

2

只有在index上需要嵌套路由,其中​​由父對象找到資源集合。否則,它是關於SEO。大多數用戶不會注意到他們的網址是如何生成的,也不關心搜索引擎。我知道你要去哪裏,但是不會生成路由,因爲這個例子中的約定用一行代碼列出了一個資源。當然,你已經知道這一點,但這只是我對事物的看法。

a) forms_path #if you want to find all forms 
b) topics_path #if you want to find all topics #possible use, maybe in a tag listing. 
c) posts_path #if you want to find all posts #probably never use 

您可能永遠都不想查找所有主題,特別是帖子,但這些將是要使用的路線。

d) form_topics_path(form) #find all topics of a given form 
e) form_topic_path(form, topic) #only find one topic on a give form 
f) topic_path #find a given topic 

在最後兩個e和f中,因爲您知道您想要哪個主題,所以不需要該表單。如果你擔心搜索引擎優化,並讓你的網站很適合搜索引擎,那麼可能要使用e。

g) form_topic_posts_path(form, topic) #I'm already confused 
h) form_topic_post_path(form, topic, post) #still to deep 
i) topic_posts_path(topic) #most rails people think two levels is deep enough 
j) topic_post_path(topic, post) #might be good for seo 

這真是SEO的問題,並保持你的網址,友好的,除了那些需要它們的父ID找到相關職位,如傳遞form找到相關主題,並傳遞topic找到嵌套資源相關文章。

如果使用topic_pathtopics_pathpost_pathpost_path你是切切實實的更好的網址,但在具有引擎來讀,但他們真的是不必要的更好網址方面錯過了。

就沒有生成路由而言,實際上並不需要這樣做,因爲這會使得這比在一行中聲明資源更復雜,其中最終目標只是管家。

1

我通過限制什麼路線,每條路線資源聲明解決我的問題產生:

resources :forums do 
    resources :topics, only: [ :index, :new, :create ] 
end 

scope except: [ :new, :create ] do 
    resources :posts 
    resources :topics do 
    resources :posts, only: [ :index, :new, :create ] 
    end 
end 

至於控制器的問題,我只是檢查是否有id傳遞:

# Topics#index 
if forum_id = params[:forum_id] 
    @topics = Forum.find(forum_id).topics.paginate page: params[:page] 
else 
    @topics = Topic.paginate page: params[:page] 
end