13note.

なんか調べたりまとめたり感想言ったりする語彙力不足及び眠気と戦うブログ

routes.rb の書き方

毎回、「routes.rbの書き方っていっぱいあるんだよね…どれが適切なのかわからんね…」ってなるので、ためすすがめつ記録してみます。


■resources

RESTに従ったアクションを一通り作ってくれる記法。

resources :users

設定される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
■resource

resourcesに対してこちらは単数リソースのルーティングを設定する。

resource :user
  Prefix Verb   URI Pattern          Controller#Action
 new_user GET    /user/new(.:format)  users#new
edit_user GET    /user/edit(.:format) users#edit
     user GET    /user(.:format)      users#show
          PATCH  /user(.:format)      users#update
          PUT    /user(.:format)      users#update
          DELETE /user(.:format)      users#destroy
          POST   /user(.:format)      users#create

単数リソースとはなんぞ?
=> 集合を扱うindexアクションはなし。
また、show,edit,update,destroyにはid の指定がなくなる。

■resourcesのネスト

resourcesに対してネストでの指定が可能。
例えば「学年(glades)」「クラス(classes)」が入れ子の場合

  resources :grades do
    resources :classes 
  end
   grade_classes GET    /grades/:grade_id/classes(.:format)          classes#index
                 POST   /grades/:grade_id/classes(.:format)          classes#create
 new_grade_class GET    /grades/:grade_id/classes/new(.:format)      classes#new
edit_grade_class GET    /grades/:grade_id/classes/:id/edit(.:format) classes#edit
     grade_class GET    /grades/:grade_id/classes/:id(.:format)      classes#show
                 PATCH  /grades/:grade_id/classes/:id(.:format)      classes#update
                 PUT    /grades/:grade_id/classes/:id(.:format)      classes#update
                 DELETE /grades/:grade_id/classes/:id(.:format)      classes#destroy
          grades GET    /grades(.:format)                            grades#index
                 POST   /grades(.:format)                            grades#create
       new_grade GET    /grades/new(.:format)                        grades#new
      edit_grade GET    /grades/:id/edit(.:format)                   grades#edit
           grade GET    /grades/:id(.:format)                        grades#show
                 PATCH  /grades/:id(.:format)                        grades#update
                 PUT    /grades/:id(.:format)                        grades#update
                 DELETE /grades/:id(.:format)                        grades#destroy

親要素のgradesのRESTのアクションに加え、それぞれのgrade(id)の小要素classesのアクションも定義されている。
ネストの構造は、複数リソースの下位に単数リソースの指定も可能。 userは複数いるが、userに対するpasswordは1対1の関係である場合、以下のような定義ができる。

  resources :users do
    resource :password
  end
new_user_password GET    /users/:user_id/password/new(.:format)       passwords#new
edit_user_password GET    /users/:user_id/password/edit(.:format)      passwords#edit

     user_password GET    /users/:user_id/password(.:format)           passwords#show
                   PATCH  /users/:user_id/password(.:format)           passwords#update
                   PUT    /users/:user_id/password(.:format)           passwords#update
                   DELETE /users/:user_id/password(.:format)           passwords#destroy
                   POST   /users/:user_id/password(.:format)           passwords#create
             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

prefixに記載されているusersとかは、ヘルパーとして?users_path,users_urlなどで該当のアクションを呼び出すURLを取得できる。
ネストしている場合も同様。

■resourceベースではないrouteの定義
  • get '{呼び出しパス}', to: '呼び出しコントロール#アクション'
get 'users', to: 'users#index'
Prefix Verb URI Pattern      Controller#Action
 users GET  /users(.:format) users#index

resouces :users を指定したときのindexと同義。

  • get '{呼び出しパス}', :controller => 'コントローラー', :action =>'アクション'
get 'users', :controller => 'users', :action => 'index'
Prefix Verb URI Pattern      Controller#Action
 users GET  /users(.:format) users#index

これも結果は同じく。
ついでにこれも…ハッシュの記法?が理解できていないのが否めない。コロンの位置(シンボル?)とアロー演算子の役割が変わっただけ…。

get 'users', controller: 'users', action: 'index'
  • idを含める
get 'user/:id', to: 'users#show'
      GET  /user/:id(.:format) users#show

これにas:をつけるとurlやpathの呼び出しが可能。(同じ名前は不可)

get 'users', controller: 'users', action: 'index', as: 'users_show'
irb(main):003:0> app.user_show_path
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"users"}, missing required keys: [:id]

(該当のコントローラは作っていないのでErrorで正)

  • どのhttpメソッドでも呼べるやつ【非推奨】 get/post/put/update/deleteどれでも該当する。
match 'users', to: 'users#someting', via: [:get, :post]
Prefix Verb     URI Pattern      Controller#Action
 users GET|POST /users(.:format) users#someting
■namespaceによるパスのグループ

同名の処理のエイリアスのために使うらしい。devise使った時にadminとuser分けたり?した時に使った気もしなくもない。

namespace :admins do
    resources :sessions
  end
  namespace :users do
    resources :sessions
  end
             Prefix Verb   URI Pattern                         Controller#Action
    admins_sessions GET    /admins/sessions(.:format)          admins/sessions#index
                    POST   /admins/sessions(.:format)          admins/sessions#create
 new_admins_session GET    /admins/sessions/new(.:format)      admins/sessions#new
edit_admins_session GET    /admins/sessions/:id/edit(.:format) admins/sessions#edit
     admins_session GET    /admins/sessions/:id(.:format)      admins/sessions#show
                    PATCH  /admins/sessions/:id(.:format)      admins/sessions#update
                    PUT    /admins/sessions/:id(.:format)      admins/sessions#update
                    DELETE /admins/sessions/:id(.:format)      admins/sessions#destroy
     users_sessions GET    /users/sessions(.:format)           users/sessions#index
                    POST   /users/sessions(.:format)           users/sessions#create
  new_users_session GET    /users/sessions/new(.:format)       users/sessions#new
 edit_users_session GET    /users/sessions/:id/edit(.:format)  users/sessions#edit
      users_session GET    /users/sessions/:id(.:format)       users/sessions#show
                    PATCH  /users/sessions/:id(.:format)       users/sessions#update
                    PUT    /users/sessions/:id(.:format)       users/sessions#update
                    DELETE /users/sessions/:id(.:format)       users/sessions#destroy
■moduleによるグループ
scope module: :admins do
    resources :sessions
end

または
  resources :sessions, module: :admin
      Prefix Verb   URI Pattern                  Controller#Action
    sessions GET    /sessions(.:format)          admin/sessions#index
             POST   /sessions(.:format)          admin/sessions#create
 new_session GET    /sessions/new(.:format)      admin/sessions#new
edit_session GET    /sessions/:id/edit(.:format) admin/sessions#edit
     session GET    /sessions/:id(.:format)      admin/sessions#show
             PATCH  /sessions/:id(.:format)      admin/sessions#update
             PUT    /sessions/:id(.:format)      admin/sessions#update
             DELETE /sessions/:id(.:format)      admin/sessions#destroy

Controller#Actionはnamespaceと同じくエイリアスを指定しているが、URIはscopeに指定した文字列を含まない。


参考: 

Railsのルーティングを極める (後編)