rails routes member と collectionの違い


rails routes member と collectionの違い

resources(RESTfulルーティング)を利用すると7つのデフォルトのルーティング(index,create,new,edit,show,update,destroy)が自動で生成されます.

ただ,自分で定義した独自のアクションへのルーティングを設定する場合はmemberまたはcollectionというオプションを利用する必要があります。

その際に,memberとcollectionの違いが気になり調べたので両者の違いをまとめます。

目次

はじめに

検証用にPostsコントローラへのルーティングファイルを作成します.

routes.rb
Rails.application.routes.draw do
    resources :posts 
end

デフォルトで以下の7つのルーティングが生成されます.(index,create,new,edit,show,update,destroy)

 Prefix Verb   URI Pattern               Controller#Action
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

やりたいこと

今回,Postsコントローラにmypostsアクションを定義したのでルーティングを追加したい

やり方

collectionを以下のように追記します.

routes.rb
Rails.application.routes.draw do
 resources :posts do
  +  collection do
   +   get 'myposts'
  +  end
  end
end

mypostsアクションへのルーティングができています。

memberとの違いは?

一言でいうと:idが付くか,付かないかです。
試しに実装してみます。

routes.rb
Rails.application.routes.draw do
  resources :posts do
  +  member do
   +   get 'myposts'
  +  end
  end
end


idがついているのがわかります。

つまり以下の用途で使い分けます。

  1. アクションにidを渡したいとき -> memberオプション
  2. idを渡す必要がないとき -> collectionオプション

*詳細はRailsガイド参照

おまけ

アクションが1つだけのとき

今回のようにカスタムアクションが1つだけの場合はon :オプションが使えます。

Rails.application.routes.draw do
  resources :posts do
      get 'myposts', on: :collection
  end
end
       Prefix Verb   URI Pattern               Controller#Action
myposts_posts GET    /posts/myposts(.:format)  posts#myposts
        posts GET    /posts(.:format)          posts#index
              POST   /posts(.:format)          posts#create
     new_post GET    /posts/new(.:format)      posts#new
    edit_post GET    /posts/:id/edit(.:format) posts#edit
         post GET    /posts/:id(.:format)      posts#show
              PATCH  /posts/:id(.:format)      posts#update
              PUT    /posts/:id(.:format)      posts#update
              DELETE /posts/:id(.:format)      posts#destroy