嵌套资源 - 如何避免冗余路由?

我有这个资源树: 论坛 话题 岗位 我希望能够尽可能独立地访问它们。我想避免像
/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/topics
还是
GET /topics
?     
已邀请:
只有在父对象找到资源集合的
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_path
topics_path
post_path
post_path
,你可能会错过更好的网址,但是为了更好的网址,你可以阅读它们,但它们确实是不必要的。 在没有生成路线的情况下,确实没有对此的需求,因为这会使这比仅仅在最终目标只是内务管理的一行中声明资源更复杂。     
我通过限制每个资源声明生成的路由来解决我的问题:
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
    

要回复问题请先登录注册