Ruby
Rails
RubyonRails5の上手な使い方

一連の記事の目次
rails、君に決めた!!~目次

Railsルータの整理整頓

namespace

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

config/routes.rb

Rails.application.routes.draw do
  resources :users

  namespace :admin do
    resources :users
  end
end

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

$ 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に以下のように作成しないといけないらしい、、。ミスりそう

module admin
  class UsersController < ApplicationController
    # actions
  end
end 
bin/rails g controller admin/users

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

namespaceを多段にネストする

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

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
通常のネスト

Rails.application.routes.draw do
  resources :users do
    resources :articles
  end
end
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

Rails.application.routes.draw do
  resources :users, shallow: true do
    resources :articles
  end
end
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 などのデフォルトの7つのアクションの他に、独自のアクションを追加できる。collectionやmemberを使う(?)

config/routes.rb

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

    member do
      # markdown形式で表示するrowアクション
      get 'raw'
    end
  end
end
         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

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文字以内の英数字に限定している。

オプショナルパラメータ

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

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

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

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

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