Railsのルーティングついて

# 概要
Railsアプリケーションでのルーティングについてまとめました。

# 今回のゴール
『ルーティングの効果』と『実践的な使い方』を確認することです。

# <1>ルーティングの効果
**結論**
・HTTPリクエストをもとに、コントローラーとアクションに処理を渡せるようになる。
・ヘルパーメソッドにより、コントローラーやビューでパスとURIを作成できるようになる。

## コントローラーとアクションの指定方法
ルーティングではクライアントからのHTTPリクエストを下記のコードで振り分けます。

```:ルーティングのイメージ
  [HTTPメソッド] '[URIのパス]', to: '[コントローラー名]#[アクション名]'

  例) get 'samples', to: 'samples#index'
```

つまり、今回の例ですと...

クライアントから**『GETメソッド』**で**『samplesのパス』**でアクセスがきたら
Railsアプリケーションの**『samplesコントローラー』**の**『indexアクション』**で処理をします

という意味になります。


## コントローラーやビューでパスとURLヘルパーが使えるようになる
ルーティングが記述されることにより、Railsアプリケーション内で**『\_pathメソッド』・『\_urlメソッド』**使えるようになります。
このメソッドにより、コントローラーでのredirect_toメソッドやビューのlink_toメソッドなどがpathを使って記述できるようになります。
### \_pathメソッド ・ \_urlメソッド
**『[Prefix]\_path』**や**『[Prefix]\_url』**のように使うことで、簡単にパスやURL生成するヘルパーメソッドです。

※ **Prefix**については後ほど、説明します。

# <2> 実践的な使い方
## ルーティングの設定場所
`config/routes.rb`ファイルになります。

```ruby:config/routes.rb
  Rails.application.routes.draw do
    get 'samples', to: 'samples#index'
  end
```

## ルーティングの確認方法
ターミナルを使い、アプリケーションのディレクトリで`rails routes`とコマンドを実行すると確認できます。

```:ターミナル
   (アプリケーションのディレクトリ)$ rails routes

      Prefix    Verb    URI Pattern             Controller#Action
     samples    GET     /samples(.:format)      samples#index

```
**『Prefix』・『Verb』・『URI Pattern』・『Controller#Action』**の四つの項目が表示されます。
**『VerbとURI Pattern』**の組み合わせで、HTTPリクエスト内容を判断して
**『Controller#Action』**で処理を渡す先を示しています。


### Prefixとは
『\_pathメソッド』・『\_urlメソッド』を使う際に利用される、変数のようなものです。

　　例）samples_path 　=>　 " /samples "
　　　　samples_url 　　=>　 " http://sample.com/samples "

### Verb(HTTP動詞)とは
処理判断するHTTPメソッドになります。

### URI Patternとは
処理判断するURIのパスになります。

### Controller#Actionとは
処理を渡すコントローラー名とアクション名になります。

## 基本の７種類のアクション
Railsには標準的に使う**『７種類のアクション』**が設定されています。


|アクション名|使用目的|
|:-:|:--|
|index  |一覧表示する|
|new    |新規のデータフォームを表示する|
|create |新規データを登録する|
|show   |特定のデータを表示する|
|edit   |特定データの編集フォームを表示する|
|update |特定データを更新する|
|destroy|特定データを削除する|

## 基本的なルーティングの記述方法
大きく分けると２つに分けることが出来ます。
**『個別設定』**と**『一括設定』**です。

### 個別設定
ルーティングを**１行ずつ**設定するコードなります。

```ruby
  Rails.application.routes.draw do
    get  'samples',     to: 'samples#index'
    post 'samples',     to: 'samples#create'
    put  'samples/:id', to: 'samples#update'
  end
```

### 一括設定(リソースベースなルーティング)
複数のルーティング設定を短いコードで書くことが出来ます。
#### resources (複数形リソース)
１行で**7つのアクション**のルーティング設定が可能なコードです。

```ruby
  Rails.application.routes.draw do
    resources :samples
  end
```

以下の個別設定ルーティングと同じ

```ruby
  Rails.application.routes.draw do
    get    'samples',          to: 'samples#index'
    post   'samples',          to: 'samples#create'
    get    'samples/new',      to: 'samples#new',   as: 'new_sample'
    get    'samples/:id/edit', to: 'samples#edit',  as: 'edit_sample'
    get    'samples/:id',      to: 'samples#show',  as: 'sample'
    patch  'samples/:id',      to: 'samples#update'
    put    'samples/:id',      to: 'samples#update'
    delete 'samples/:id',      to: 'samples#destroy'
  end
```

##### ※ asオプション
**『as: 'XXX'』**とすることで、**Prefixに『XXX』**と指定することが出来ます。

#### resource (単数形リソース)
１行で**indexアクション以外の6つのアクション**のルーティング設定が可能なコードです。
アプリケーション設計の中で、**各ユーザーがひとつの情報(リソース)しか持たない時**に使います。
ひとつの情報しか持たないため、indexアクション(複数リソースを一覧表示する)がなく
URIのパスに**『:id』**がつきません。

また、**コントローラーは複数形**になることに注意が必要です。

```ruby
  Rails.application.routes.draw do
    resource :sample  # 単数形になっている
  end
```

以下の個別設定ルーティングと同じ

```ruby
  Rails.application.routes.draw do
    post   'sample',          to: 'samples#create'
    get    'sample/new',      to: 'samples#new',   as: 'new_sample'
    get    'sample/edit',     to: 'samples#edit',  as: 'edit_sample'
    get    'sample',          to: 'samples#show',  as: 'sample'
    patch  'sample',          to: 'samples#update'
    put    'sample',          to: 'samples#update'
    delete 'sample',          to: 'samples#destroy'
  end
```
## 応用的なルーティングの記述方法
### リソースベースなルーティングの制限
resources/resourceのルーティングのアクションを一部を使用したい時に
**『onlyオプション』**・**『exceptオプション』**を指定します。

```ruby
  Rails.application.routes.draw do
    # index・showアクションのみを使用
    resources :users, only: [:index, :show]

    # index・show・edit・update・destroyアクション以外を使用
    resources :books, except: [:index, :show, :edit, :update , :destroy]
  end
```

```
   $ rails routes

    Prefix Verb   URI Pattern               Controller#Action
     users GET    /users(.:format)          users#index 
      user GET    /users/:id(.:format)      users#show
     books POST   /books(.:format)          books#create
  new_book GET    /books/new(.:format)      books#new

```

### リソースベースなルーティングに対して、アクションの追加
Railsの７つ基本的なアクション以外にも、**『memberルーティング』**・**『collectionルーティング』**でアクションを追加することができます。

#### memberルーティングとは
URIのパスに**『:id』**を含んだルーティング方法です。

```ruby:memberルーティング
  Rails.application.routes.draw do
    resources :photos do
      member do
        get 'preview'
      end
    end
  end
```

```
  $ rails routes

         Prefix Verb   URI Pattern                   Controller#Action
  preview_photo GET    /photos/:id/preview(.:format) photos#preview
         photos GET    /photos(.:format)             photos#index

```

#### collectionルーティングとは
URIのパス**『:id』**を含まないルーティング方法です。
コードの記述方法は、memberルーティングと同じです。

#### URIのパスの『:id』の有無で何が変わるのか
『id』とはアプリケーション内で登録したデータの管理番号です。
パスに『id』があるということは、『そのアクションを実行する時に、管理番号で必要なデータを特定している』ということになります。

例えばRailsの７つの基本アクションで説明すると
**index・new・createアクション**にはパスに『id』がありません。
なぜかというと、**一覧表示するために特定のデータ**はいらないですし、**これから登録するデータ**には『id』がないからです。

その逆に、**show・edit・update・destroyアクション**は
**登録された特定のデータを表示したり、変更したり、削除したりする**ので
『id』がないと**どのデータのことかわからない**ため、パスに『id』が入っています。


### ネストしたリソースのルーティング
#### ネストとは
『入れ子』という意味です。
ルーティングに親要素の中に入れ子構造で子要素を入れて記述することを表します。

```ruby:例)ネストしたリソースのルーティング
  Rails.application.routes.draw do
    resources :books do
      resources :reviews
    end
  end
```

今回の例だと、booksという親要素に、reviewsという子要素が入れ子構造になっています。

#### ルーティングへの効果
ネストしたルーティングすることによって、子要素のルーティングに親要素を関連付けることができます。
上記の例の場合だと、必ずreviews(子要素)はある特定のbook(親要素)に結びついていることになります。
reviews(子要素)のルーティングを確認するとこうなります。

```
          Prefix Verb   URI Pattern                                Controller#Action
    book_reviews GET    /books/:book_id/reviews(.:format)          reviews#index
                 POST   /books/:book_id/reviews(.:format)          reviews#create
 new_book_review GET    /books/:book_id/reviews/new(.:format)      reviews#new
edit_book_review GET    /books/:book_id/reviews/:id/edit(.:format) reviews#edit
     book_review GET    /books/:book_id/reviews/:id(.:format)      reviews#show
                 PATCH  /books/:book_id/reviews/:id(.:format)      reviews#update
                 PUT    /books/:book_id/reviews/:id(.:format)      reviews#update
                 DELETE /books/:book_id/reviews/:id(.:format)      reviews#destroy
```

**『Prefix』**と**『URI Pattern』**の項目にネストの効果があります。

##### Prefix への効果
子要素の前に親要素が入ります。
`book_reviews`や`new_book_review`などの親要素(book)が入ったPrefixになります。

##### URI Pattern への効果
子要素の前に親要素と親要素のidが入ります。
`/books/:book_id/reviews`という親要素(book)が入ったURI Patternになります。
`/books/:book_id`の部分が特定の親要素を表すパスとなり
『子要素がどの親要素とつながりがあるか』が明示的に示されるようになります。



以上になります。