rails、君に決めた！！~6

一連の記事の目次
[rails、君に決めた！！~目次](https://qiita.com/satousatou/items/d20b61c198a4d439f2e7)

## Railsルータの整理整頓

#### namespace
URLとコントローラに階層を追加できる
例えば一般ユーザーと管理ユーザーを作りたい時、同じusersというリソースから２つの名前空間を作って、処理を分離できる。

config/routes.rb

```ruby
Rails.application.routes.draw do
  resources :users

  namespace :admin do
    resources :users
  end
end
```

ルーティングを出力してみる

```bash
$ bin/rails routes
         Prefix Verb   URI Pattern                     Controller#Action
          users GET    /users(.:format)                users#index
                POST   /users(.:format)                users#create
       new_user GET    /users/new(.:format)            users#new
      edit_user GET    /users/:id/edit(.:format)       users#edit
           user GET    /users/:id(.:format)            users#show
                PATCH  /users/:id(.:format)            users#update
                PUT    /users/:id(.:format)            users#update
                DELETE /users/:id(.:format)            users#destroy
    admin_users GET    /admin/users(.:format)          admin/users#index
                POST   /admin/users(.:format)          admin/users#create
 new_admin_user GET    /admin/users/new(.:format)      admin/users#new
edit_admin_user GET    /admin/users/:id/edit(.:format) admin/users#edit
     admin_user GET    /admin/users/:id(.:format)      admin/users#show
                PATCH  /admin/users/:id(.:format)      admin/users#update
                PUT    /admin/users/:id(.:format)      admin/users#update
                DELETE /admin/users/:id(.:format)      admin/users#destroy
```

`namespace :admin`ブロックで囲むと、URIとコントローラの階層が一段深くなるんだー、便利。
> ディレクトリの階層とモジュールの階層も一段深くする必要がある

admin/usersに対応するコントローラは
app/controllers/admin/users_controller.rbに以下のように作成しないといけないらしい、、。ミスりそう

```ruby
module admin
  class UsersController < ApplicationController
    # actions
  end
end 
```

```bash
bin/rails g controller admin/users
```

のように[/]で区切ったgenerateコマンドを使うと、同じことができる！！

##### namespaceを多段にネストする  
/api/v2/books/10と/api/v3/books/10のようなエンドポイントを作成する 
(APIのバージョニング戦略と呼ぶらしい)時のように、多段なルーティングをする場合以下のように記述する。

```ruby
Rails.application.routes.draw do
  namespace :api do
    namespace :v3 do
      resources :books
    end
    namespace :v2 do
      resources :books
    end
  end
end
```

#### ネストされたroutesをshallowメソッドで簡潔にする
id:1のユーザーに紐づいた記事を表現したい場合、RESTでは`users/:user_id/articles/:article_id`のように表現する。ただこれって冗長だよね、article_idが一意なら`/articles/:id`でいいじゃんっていうのを実現するのがshallowメソッド（浅いルーティング）

config/routes.rb
通常のネスト

```ruby
Rails.application.routes.draw do
  resources :users do
    resources :articles
  end
end
```

```bash
Prefix Verb   URI Pattern                                 Controller#Action
    user_articles GET    /users/:user_id/articles(.:format)          articles#index
                  POST   /users/:user_id/articles(.:format)          articles#create
 new_user_article GET    /users/:user_id/articles/new(.:format)      articles#new
edit_user_article GET    /users/:user_id/articles/:id/edit(.:format) articles#edit
     user_article GET    /users/:user_id/articles/:id(.:format)      articles#show
                  PATCH  /users/:user_id/articles/:id(.:format)      articles#update
                  PUT    /users/:user_id/articles/:id(.:format)      articles#update
                  DELETE /users/:user_id/articles/:id(.:format)      articles#destroy
            users GET    /users(.:format)                            users#index
                  POST   /users(.:format)                            users#create
         new_user GET    /users/new(.:format)                        users#new
        edit_user GET    /users/:id/edit(.:format)                   users#edit
             user GET    /users/:id(.:format)                        users#show
                  PATCH  /users/:id(.:format)                        users#update
                  PUT    /users/:id(.:format)                        users#update
                  DELETE /users/:id(.:format)                        users#destroy
```

shallow

```ruby
Rails.application.routes.draw do
  resources :users, shallow: true do
    resources :articles
  end
end
```

```bash
Prefix Verb   URI Pattern                            Controller#Action
   user_articles GET    /users/:user_id/articles(.:format)     articles#index
                 POST   /users/:user_id/articles(.:format)     articles#create
new_user_article GET    /users/:user_id/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
           users GET    /users(.:format)                       users#index
                 POST   /users(.:format)                       users#create
        new_user GET    /users/new(.:format)                   users#new
       edit_user GET    /users/:id/edit(.:format)              users#edit
            user GET    /users/:id(.:format)                   users#show
                 PATCH  /users/:id(.:format)                   users#update
                 PUT    /users/:id(.:format)                   users#update
                 DELETE /users/:id(.:format)                   users#destroy
```

#### アクションの追加
GET index や　GET show などのデフォルトの７つのアクションの他に、独自のアクションを追加できる。collectionやmemberを使う(?)

config/routes.rb

```ruby
Rails.application.routes.draw do
  resources :articles do
    collection do
      # 検索を行うsearchアクション
      get 'search'
    end

    member do
      # markdown形式で表示するrowアクション
      get 'raw'
    end
  end
end
```

```bash
         Prefix Verb   URI Pattern                  Controller#Action
search_articles GET    /articles/search(.:format)   articles#search
    raw_article GET    /articles/:id/row(.:format)  articles#row
       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
```

collection: indexアクションのように、リソース全体に対してのアクション
member: showアクションのように、:idで指定した個々のリソースに対するアクション
っていうのが違う。

#### URLのパラメータに制約をかける
なんで制約かけるの
→　不正なリクエストを送れないように

どうやって
→　constrainsオプション+正規表現

config/routes.rb

```ruby
Rails.application.routes.draw do
  get 'users/@:user_name', to: 'users#index', constraints{
    user_name: /[a-zA-Z]{1,5}/
  }
end
```

user_nameを1~5文字以内の英数字に限定している。

#### オプショナルパラメータ
> ルーティングのパスパラメータを括弧()で括ることで、省略可能なオプショナルパラメータを指定できる

全然わからないのでとりあえず例を見てみる

```ruby
Rails.application.routes.draw do
  get '(:locale)/users', to: 'users#index', locale: /en|ja/
end
```

/usersと/en/usersどっちにも対応してる。多言語対応できる。

うーん、なんとなくはわかる。眠くて頭が、、今日はここまでzzz