LoginSignup
3
2

More than 1 year has passed since last update.

【初心者】resources, resource, member, collection, namespaceの使い分け

Last updated at Posted at 2021-06-06

先に結論

・resources

リソースのCRUDをRestfulに実現するためにRailsが用意しているメソッド
[使いどころ]
RailsでCRUDを実現するためのメソッド(index, show, new, create, edit, update)を使いたい時にまとめて設定できる。

・resource

recourcesと同じ。違うところは、リソースが複数できることがない時。
つまり、indexアクションがない時。
[使いどころ]
リソースが複数存在する可能性がない時。
dashboardとかもある意味リソースがひとつか?

・member

個別のリソースに対して基本の7つ以外のアクションを作成できる。
[使いどころ]
リソースとして切り分けるほどでもない小さい概念を扱いたい。
その時、どうしても基本アクション以外が欲しい時。
collectionとの違いは、ネストの親リソースの個別にURLが欲しい時。
ex) Tweetsのreviewなど。個別のツイートに対してレビューが存在する。

・collection

個別のリソースに対して基本の7つ以外のアクションを作成できる。
[使いどころ]
リソースとして切り分けるほどでもない小さい概念を扱いたい。
その時、どうしても基本アクション以外が欲しい時。
memberとの違いは、ネストの親リソースに対して個別のURLが必要ない時。
ex) Tweetsのsearchなど。ツイート全体に対して「探す」という機能が存在する。

・namespace

全部やっちゃう子
Prefix, Verb, URI, Pattern, Controller#Action
が全てネストされる。

scope

Prefix, Controller#Actionはそのままに、URI Patternだけネストしちゃう。

scope module:

Prefix, URIPatternはそのままに、Controller#Actionだけネストしちゃう。

これだけではわからないと思うので、以下で解説。

ResourcesとResourceの違い

resources... 基本的なRestの機能を実現するためのアクションを自動生成
resource ... ひとつしかできる余地のないリソースに対して使用。URLにidの記述がなくなる

routes.rb
resource :hoge
ターミナル
$rails routes

 new_hoge GET    /hoge/new(.:format)     hoges#new
edit_hoge GET    /hoge/edit(.:format)    hoges#edit                                                                
     hoge GET    /hoge(.:format)         hoges#show                                                           
          PATCH  /hoge(.:format)         hoges#update                                                                
          PUT    /hoge(.:format)         hoges#update                                                                 
          DELETE /hoge(.:format)         hoges#destroy                                                                
          POST   /hoge(.:format)         hoges#create                                                                 

ご覧の通り、indexがない。ひとつのリソースしか存在しない前提なので、indexは作られない。
注意ポイントは、URLはhogesではなく、hoge(単数系ルーティング)になっていること。
コントローラーはhogesのままだから間違えやすいポイント。
(基本的に、resourcesとネストさせずに単体で使うことはないかも?)

member, collection

member

memberは、個別のリソースに対して基本の7つ以外のアクションを作成できる。
※基本の7つとは、index, show, new, create, edit, update, delete

routes.rb
 resources :tweets do
    member do
      get 'review'
    end
  end
ターミナル
Prefix        Verb       URI Pattern               Controller#Action
review_tweet  GET    /tweets/:id/review(.:format)   tweets#review

collection

collectionはリソース全体に対する基本の7つ以外のアクションを作成できる。

routes.rb
 resources :tweets do
    collection do
      get 'search'
    end
  end
ターミナル
Prefix           Verb    URI Pattern              Controller#Action
search_tweets   GET    /tweets/search(.:format)    tweets#search

memberやcollectionで独自のアクションをリソースを指定して作成できますが、できるだけRestfulな設計思想に乗っかるように、7つのアクションを使うようにしましょう。

ちょっと待て、Restとは?

Restとは、アプリケーションを構成するコンポーネント(Usersなど)を
・RDBMSのCRUD(Create/Read/Update/Delete)
・HTTPRequestの各メソッド(GET/POST/PUT/DELETE)
に対応させて、自由に**作成、読み出し、更新、削除ができるリソースとして扱うアーキテクチャ。

RailsはRestをサポートしており、その最たる例がresourcesやresource。
以上4つのメソッドを実現するアクションURLを自動で結びつけてくれる。

ネストしたルーティング

resourcesをネストさせるとURLをネストさせた形で指定できる。

例えば、アニメはたくさんのレビューを持っていると思うので、以下のようにルーティングをネストさせるべきだろう。

route.rb
Rails.application.routes.draw do
 resources :anime do
   resources :review
 end
end

こうすることで、
/animes -> anime#index
/animes/:id anime#show
などはもちろん、
/anime/anime_id/review(GET) -> review#index
/anime/anime_id/review/id(GET) -> review#show
などのように、animeにネストさせた形でreviewのURLを構成することができる。
ちなみにanime_idが絶対に入っていることからmemberを使った場合と同じURLの割り振り方であると、理解できる。

namespace

基本的に、Railsのルーティングはresourcesのネストまでを使えば表現できる。
しかし、ルーティングをグルーピングしたいときは以下のnamespaceを用いる。

routes.rb
resources :posts
  namespace :admin do
    resources :posts
  end
end

こうすることで、Postリソースの操作内容をadminユーザーの場合と、一般ユーザーの場合で分けることができます。これは、member, collectionでは実現できないことです。

/posts
/posts/:id
/admin/posts
/admin/posts/:id
と2種類のグルーピングができる

そして、コントローラーは、ネストした形にしたものを新しく作成する。

admin/posts_controller.rb
class Admin::PostsController < ApplicationController
def #メソッド(CRUD)
end

namespace以外のグルーピング方法

rails routes コマンドで出てくる情報として、Prefix、URI Pattern 、Controller#Action がある。namespaceは全部をネストした形にしてくれる。以下のメソッドはどれかだけをネストしたい場合に使われる。

・scope
・sope module:

namespace -> Prefix、URI Pattern 、Controller#Action
scope -> URI Pattern のみ
scope module: -> Controller#Actionのみ(ディレクトリ構造)

この対応によって使い分ければオッケーです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2