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

例如,

resources :photos do
  member do
    get :preview
  end
end

resources :photos do
  collection do
    get :search
  end
end

我不明白。


当前回答

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

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

2):member -与:collection相同,但用于操作在 特定的成员。

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

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

其他回答

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

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

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

2):member -与:collection相同,但用于操作在 特定的成员。

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

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

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

成员{get 'preview'}将生成:

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

集合{get 'search'}将生成:

search_photos_path # /photos/search

注意多数!

简短的回答:

成员块和集合块都允许您为资源定义除Rails将为您生成的7个标准路由之外的其他路由。

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


长回答

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

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

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_path和preview_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

这里有两个重要的区别:

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

自定义领取路线

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

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

这将添加以下新路由。它还将添加search_articles_path和search_articles_url帮助器。

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

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

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

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

结论

Rails允许您使用成员和集合块来打破使用七个资源路由的惯例。两者都允许您为资源定义除标准7条路由之外的其他路由。

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

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

                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)