LoginSignup
3
3

【Rails】よく使うルーティング記法

Posted at

はじめに

こんにちは。kosukein38です。
「こんな感じのpathにしたいんだけど、このルーティングっってどう書くんだっけ?」ってなって試行錯誤することが多かったので、ノート的によく使うルーティング記法をまとめました。

対象者

  • Railsのルーティング設定に慣れていない方

ルーティングとは

Railsガイドによると、以下の定義。

Railsのルーターは受け取ったURLを認識し、適切なコントローラ内アクションやRackアプリケーションに振り分けます。ルーターはパスやURLも生成できるので、ビューでこれらのパスやURLを直接ハードコードする必要はありません。

ざっくりとは、クライアントから受け取ったHTTPリクエストを適切なコントローラーに振り分けたり、パスやURLを簡単に生成できるようにするためのルールです。HTTPリクエストを正しいコントローラーで処理し、適切なビューを表示させたり、APIでデータを返却したりしています。

よく使うルーティング

resourcesを使ったルーティング設定

:idを含むリソース作られる。
(例)TaskモデルのCRUD

Helper HTTP Verb Path Controller#Action
tasks_path GET /tasks(.:format) tasks#index
POST /tasks(.:format) tasks#create
new_task_path GET /tasks/new(.:format) tasks#new
edit_task_path GET /tasks/:id/edit(.:format) tasks#edit
task_path GET /tasks/:id(.:format) tasks#show
PATCH(PUT) /tasks/:id(.:format) tasks#update
DELETE /tasks/:id(.:format) tasks#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  resources :tasks
end

resourceを使ったルーティング設定

:idを含むルーティングが生成されません。

(例)SettingモデルのCRUD

Helper HTTP Verb Path Controller#Action
new_settings_path GET /settings/new(.:format) settings#new
edit_settings_path GET /settings/edit(.:format) settings#edit
settings_path GET /settings(.:format) settings#show
PATCH(PUT) /settings(.:format) settings#update
DELETE /settings(.:format) settings#destroy
POST /settings(.:format) settings#create

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  resource :settings
end

名前空間を使ったルーティング設定

adminと他のリソースを分けたい時などに使います。

Helper HTTP Verb Path Controller#Action
admin_tasks_path GET /admin/tasks(.:format) admin/tasks#index
POST /admin/tasks(.:format) admin/tasks#create
new_admin_task_path GET /admin/tasks/new(.:format) admin/tasks#new
edit_admin_task_path GET /admin/tasks/:id/edit(.:format) admin/tasks#edit
admin_task_path GET /admin/tasks/:id(.:format) admin/tasks#show
PATCH(PUT) /admin/tasks/:id(.:format) admin/tasks#update
DELETE /admin/tasks/:id(.:format) admin/tasks#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  namespace :admin do
    resources :tasks
  end
end

また、以下のようにすると、できるpathは上と同様にadmin配下(admin/~~)となりますが、コントローラーはadmin配下ではなく、app/controllers/tasks_contraller.rbを参照します

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  namespace :admin do
    resources :tasks
  end
end

ネストしたルーティング設定

ネストは1回までが原則。

(例)1対多でtaskにcommentsが紐づいている場合

Helper HTTP Verb Path Controller#Action
task_comments_path GET /tasks/:task_id/comments(.:format) comments#index
POST /tasks/:task_id/comments(.:format) comments#create
new_task_comment_path GET /tasks/:task_id/comments/new(.:format) comments#new
edit_task_comment_path GET /tasks/:task_id/comments/:id/edit(.:format) comments#edit
task_comment_path GET /tasks/:task_id/comments/:id(.:format) comments#show
PATCH(PUT) /tasks/:task_id/comments/:id(.:format) comments#update
DELETE /tasks/:task_id/comments/:id(.:format)
comments#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  resources :tasks do
    resources :comments
  end
end

ネストを浅くするshallowオプションを使ったルーティング設定

edit, show, update, destroyアクションのpathが浅くなります。

Helper HTTP Verb Path Controller#Action
task_comments_path GET /tasks/:task_id/comments(.:format) comments#index
POST /tasks/:task_id/comments(.:format) comments#create
new_task_comment_path GET /tasks/:task_id/comments/new(.:format) comments#new
edit_task_comment_path GET /comments/:id/edit(.:format) comments#edit
task_comment_path GET /comments/:id(.:format) comments#show
PATCH(PUT) /comments/:id(.:format) comments#update
DELETE /comments/:id(.:format)
comments#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  shallow do
    resources :tasks do
      resources :comments
    end
  end
end

scopeメソッドに:shallow_pathオプションを使ったルーティング設定

指定されたパラメータをメンバーのパスの冒頭に追加します。

Helper HTTP Verb Path Controller#Action
task_comments_path GET /tasks/:task_id/comments(.:format) comments#index
POST /tasks/:task_id/comments(.:format) comments#create
new_task_comment_path GET /tasks/:task_id/comments/new(.:format) comments#new
edit_comment_path GET /corporation/comments/:id/edit(.:format) comments#edit
comment_path GET /corporation/comments/:id(.:format) comments#show
PATCH(PUT) /corporation/comments/:id(.:format) comments#update
DELETE /corporation/comments/:id(.:format) comments#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  scope shallow_path: "corporation" do
    resources :tasks do
      resources :comments, shallow: true
    end
  end
end

scopeメソッドに:shallow_prefixオプションを使ったルーティング設定

指定されたパラメータを(パスではなく)名前付きルーティングヘルパー名の冒頭に追加します。

Helper HTTP Verb Path Controller#Action
task_comments_path GET /tasks/:task_id/comments(.:format) comments#index
POST /tasks/:task_id/comments(.:format) comments#create
new_task_comment_path GET /tasks/:task_id/comments/new(.:format) comments#new
edit_corporation_comment_path GET /comments/:id/edit(.:format) comments#edit
corporation_comment_path GET /comments/:id(.:format) comments#show
PATCH(PUT) /comments/:id(.:format) comments#update
DELETE /comments/:id(.:format) comments#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  scope shallow_prefix: "corporation" do
    resources :tasks do
      resources :comments, shallow: true
    end
  end
end

メンバールーティングを使ったルーティング設定

デフォルトの7つのアクションに加えて、別のRESTfulなアクションを追加したい場合に使用します。メンバールーティングは:idを伴うルーティングに対して、アクションを追加したい場合に用います。

Helper HTTP Verb Path Controller#Action
reset_password_password_path GET /passwords/:id/reset_password(.:format) passwords#reset_password
assign_password_path GET /passwords/:id/assign(.:format) passwords#assign
unassign_password_path GET /passwords/:id/unassign(.:format) passwords#unassign
passwords_path GET /passwords(.:format) passwords#index
POST /passwords(.:format) passwords#create
GET /passwords/new(.:format) passwords#new
GET /passwords/:id/edit(.:format) passwords#edit
GET /passwords/:id(.:format) passwords#show
PATCH(PUT) /passwords/:id(.:format) passwords#update
DELETE /passwords/:id(.:format) passwords#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  resources :passwords do
    member do
      post 'csv_import'
    end
  end
end

コレクションルーティングを使ったルーティング設定

メンバールーティング同様、デフォルトの7つのアクションに加えて、別のRESTfulなアクションを追加したい場合に使用しますが、:idを伴わないルーティングに対して、アクションを追加したい場合に用います。

Helper HTTP Verb Path Controller#Action
csv_import_passwords_path POST /passwords/csv_import(.:format) passwords#csv_import
passwords_path GET /passwords(.:format) passwords#index
POST /passwords(.:format) passwords#create
GET /passwords/new(.:format) passwords#new
GET /passwords/:id/edit(.:format) passwords#edit
GET /passwords/:id(.:format) passwords#show
PATCH(PUT) /passwords/:id(.:format) passwords#update
DELETE /passwords/:id(.:format) passwords#destroy

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
  resources :passwords do
    member do
      post 'csv_import'
    end
  end
end

名前付きルーティング設定

:asオプションを使うと、任意のルーティングに名前を指定できます。

【asつけない場合】
Helperが生成されません

Helper HTTP Verb Path Controller#Action
GET /stations/:station_id/access_guide(.:format) stations#access_guide

上を設定する場合のルーティングの記法

config/routes.rb

Rails.application.routes.draw do
    get 'stations/:station_id/access_guide', to: 'stations#access_guide'
end

【asつけた場合】

Helperが生成されます。

Helper HTTP Verb Path Controller#Action
station_access_guide_path GET /stations/:station_id/access_guide(.:format) stations#access_guide

上を設定する場合のルーティングの記法

config/routes.rb
Rails.application.routes.draw do
  get 'stations/:station_id/access_guide', to: 'stations#access_guide', as: 'station_access_guide'
end

名前付きルーティングパラメータのオーバーライド

Railsガイドの説明が分かりやすいのでそのまま引用します。

:paramオプションは、デフォルトのリソース識別子:id(ルーティングの生成に使われる動的なセグメントの名前) をオーバーライドします。params[<:パラメータ>]を使って、コントローラからそのセグメントにアクセスできます。

param: 'token'があるとき】

Helper HTTP Verb Path Controller#Action
reservations_path POST /reservations(.:format) reservations#create
reservation_path PATCH(PUT) /reservations/:token(.:format) reservations#update

上を設定する場合のルーティングの記法

config/routes.rb
Rails.application.routes.draw do
  resources :reservations, only: [:create, :update], param: 'token'
end

param: 'token'がないとき】

Helper HTTP Verb Path Controller#Action
reservations_path POST /reservations(.:format) reservations#create
reservation_path PATCH(PUT) /reservations/:id(.:format) reservations#update

上を設定する場合のルーティングの記法

config/routes.rb
Rails.application.routes.draw do
  resources :reservations, only: [:create, :update]
end

ルーティングは探索順に注意!!

これまでの内容をふまえて、例えば以下のようなルーティングを考えてみます。

config/routes.rb
Rails.application.routes.draw do
  resources :reservations, only: [:create, :edit, :update], param: 'token' do
    member do
      get '/:reservation_no', to: 'reservations#guest_page', as: 'guest_page' 
    end
end

一見良さそうにみえるのですが、生成されるパスは以下の順番になります。

Helper HTTP Verb Path Controller#Action
guest_page_reservation_path GET /reservations/:token/:reservation_no(.:format) reservations#guest_page
reservations_path POST /reservations(.:format) reservations#create
edit_reservation_path GET /reservations/:token/edit(.:format) reservations#edit
reservation_path PATCH(PUT) /reservations/:token(.:format) reservations#update

実はこの書き方ではeditアクションのpathにアクセスすると、先にguest_pageアクションのパスがヒットしてしまい、エラーが発生します。
これはguest_pageアクションのパスが:reservation_noという動的なセグメントを含んでおり、  Railsがルーティングを探索する際に、このパスがeditアクションのパスよりも先にヒットしてしまうためです。
なので、例えば以下のように修正します。

config/routes.rb
Rails.application.routes.draw do
  get '/reservations/:token/edit', to: 'reservations#edit', as: 'edit_reservation'
  resources :reservations, only: [:create, :update], param: 'token' do
    member do
      get '/:reservation_no', to: 'reservations#guest_page', as: 'guest_page' 
    end
  end
end

そうすると生成されるパスは次のようになり、editアクションのパスが一番上に生成されるようになります。
Railsは上から順番にパスを検索するため、こうすることで正しいパスを認識するようになります。
(もっと上手い書き方があるかもしれません...)

Helper HTTP Verb Path Controller#Action
edit_reservation_path GET /reservations/:token/edit(.:format) reservations#edit
guest_page_reservation_path GET /reservations/:token/:reservation_no(.:format) reservations#guest_page
reservations_path POST /reservations(.:format) reservations#create
reservation_path PATCH(PUT) /reservations/:token(.:format) reservations#update

resourcesで書いたルーティングが一番先に生成されるのかと思いきや、ブロックの中身のルーティングが先にできて、その後ろになるのは個人的に間違えやすいポイントでした。
(中のブロックを先に評価しているからかな?)

まとめ

  • よく使うルーティング記法と、その例の出力結果をまとめました
  • 動的なセグメント(:idみたいなやつ)を使う時は、他のルーティングに影響しないかをチェックする

その他、参考記事

Railsガイド

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3