ruby on rails中集合路由和成员路由的区别?

在Rails中,集合路由和成员路由有什么区别?

例如,

resources :photos do
member do
get :preview
end
end

resources :photos do
collection do
get :search
end
end

我不明白。

101970 次浏览

成员路由需要一个ID,因为它作用于成员。而收集路由则不会,因为它作用于对象的集合。预览是成员路由的一个例子,因为它作用于(并显示)单个对象。搜索是集合路由的一个例子,因为它作用于(并显示)对象集合。

1) :集合 -为操作集合的其他动作添加命名路由。取#{action} => #{method}的哈希值,其中method为:get/:post/:put/:delete,是前面任意一个的数组,如果方法无关紧要,则为:any。这些路由映射到类似/用户/ customers_list的URL,路由为customers_list_users_url

地图。资源:users,:collection => {:customers_list=>:get}

2) :member -与:collection相同,但用于操作在a上的操作 特定的成员。< / p >

地图。资源:users,:member => {:inactive=>:post}

它被处理为/users/1;inactive=> [:action => 'inactive', :id => 1]

西奥的答案是正确的。出于文档的考虑,我还想指出,这两个程序将生成不同的路径帮助程序。

member {get 'preview'}将生成:

preview_photo_path(@photo) # /photos/1/preview

collection {get 'search'}将生成:

search_photos_path # /photos/search

注意多数!

                URL                 Helper                      Description
----------------------------------------------------------------------------------------------------------------------------------
member          /photos/1/preview   preview_photo_path(photo)   Acts on a specific resource so required id (preview specific photo)
collection      /photos/search      search_photos_path          Acts on collection of resources(display all photos)

简短的回答:

membercollection块都允许你为你的资源定义额外的路由,而不是Rails为你生成的7个标准路由。

  • member块在资源的单个成员上创建新路由。
  • collection块为该资源的集合创建新路由。

长回答

Rails提供了membercollection块,因此你可以为资源集合和单个资源定义自定义路由。

下面是为文章资源定义路由的典型方式。

resources :articles

这将创建以下路由。

➜ bin/rails routes -g article


Prefix Verb   URI Pattern                  Controller#Action
articles GET    /articles(.:format)          articles#index
POST   /articles(.:format)          articles#create
new_article GET    /articles/new(.:format)      articles#new
edit_article GET    /articles/:id/edit(.:format) articles#edit
article GET    /articles/:id(.:format)      articles#show
PATCH  /articles/:id(.:format)      articles#update
PUT    /articles/:id(.:format)      articles#update
DELETE /articles/:id(.:format)      articles#destroy

但是让我们假设你正在以低价写文章,并且需要在你写的时候看到文章的预览。

你可以创建一个PreviewController并使用它的show动作来显示文章的预览,但是在ArticlesController本身上添加预览动作更方便。

自定义成员路由

下面是如何使用成员块在ArticlesController上定义预览路由。

resources :articles do
member do
get 'preview'
end
end

它添加了一个新的路由,将请求指向ArticlesController#preview操作。其余路线保持不变。它还在params[:id]中传递文章id,并创建preview_article_pathpreview_article_url helper。

➜ bin/rails routes -g article


Prefix Verb   URI Pattern                     Controller#Action
preview_article GET    /articles/:id/preview(.:format) articles#preview


... remaining routes

如果你只有一个成员路由,通过将:on选项传递给路由来使用简写版本,消除阻塞。

resources :articles do
get 'preview', on: :member
end

你可以更进一步,去掉:on选项。

resources :articles do
get 'preview'
end

它生成以下路由。

➜  bin/rails routes -g preview


Prefix Verb URI Pattern                         Controller#Action
article_preview GET  /articles/:article_id/preview(.:format) articles#preview

这里有两个重要的区别:

  1. 文章的id可用为params[:article_id]而不是params[:id]
  2. 路由助手从preview_article_path变为article_preview_path,从preview_article_url变为article_preview_url

自定义领取路线

若要为资源的集合添加新路由,请使用集合块。

resources :articles do
collection do
get 'search'
end
end

这将添加以下新路由。它还将添加search_articles_pathsearch_articles_url帮助器。

search_articles GET    /articles/search(.:format)   articles#search

如果不需要多个collection路由,只需将:on选项传递给路由。

resources :articles do
get 'search', on: :collection
end

这将添加与上面相同的路由。

结论

Rails允许您使用membercollection块来打破使用七个足智多谋的路由的惯例。两者都允许您为资源定义除标准7条路由之外的其他路由。

member块作用于资源的单个成员,而collection块作用于该资源的集合。

来源:使用成员块和集合块定义新路由