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

#先に結論

###・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の記述がなくなる

```ruby:routes.rb
resource :hoge
```

```ruby:ターミナル
$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

```ruby:routes.rb
 resources :tweets do
    member do
      get 'review'
    end
  end
```

```ruby:ターミナル
Prefix        Verb       URI Pattern               Controller#Action
review_tweet  GET    /tweets/:id/review(.:format)   tweets#review
```

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


```ruby:routes.rb
 resources :tweets do
    collection do
      get 'search'
    end
  end
```

```ruby:ターミナル
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をネストさせた形で指定できる。

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

```ruby: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を用いる。

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

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

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

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

```ruby: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のみ(ディレクトリ構造)

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