やりたいこと
あるルーティングがどこで定義されているかを調べたい。
例
巨大な config/routes.rb
ファイルがあり、たくさんのルーティングが定義されている。
# 1,000 行を超えた巨大な routes.rb ファイル。
Rails.application.routes.draw do
# 略
resources :brands, only: %i(index show) do
resources :yoyos
end
# 略
end
bin/rails routes --unused
コマンドを実行して、使用していないルーティングを調べてみる。そうすると BrandsController
は only
オプションで index
と show
しか定義していないにもかかわらず、なぜか create
, new
, edit
, update
, destroy
といった他のアクションのルーティングも定義されている。
今回はこれらの想定していないルーティングがどこで定義されているかを調べてみる。
$ bin/rails routes --unused
Found 6 unused routes:
Prefix Verb URI Pattern Controller#Action
POST /brands(.:format) brands#create
new_brand GET /brands/new(.:format) brands#new
edit_brand GET /brands/:id/edit(.:format) brands#edit
PATCH /brands/:id(.:format) brands#update
PUT /brands/:id(.:format) brands#update
DELETE /brands/:id(.:format) brands#destroy
方法
例えば brands#create
のルーティングがどこで定義されているのか調べてみよう。Rails コンソールで以下のコードを実行する。
# それぞれの返り値の型のメモ。
# Rails.application.routes
#=> #<Rails::Engine::LazyRouteSet:0x000000012a8ffa18>
# Rails.application.routes.routes
#=> #<ActionDispatch::Journey::Routes:0x00000001299f45c8>
# Rails.application.routes.routes.first
#=> #<ActionDispatch::Journey::Route:0x000000012a712db8>
routes = Rails.application.routes.routes
route = routes.find { it.requirements in { controller: 'brands', action: 'create' } }
route.source_location
#=> "/Users/quanon/workspace/mogura_no_yoyo_shop/config/routes.rb:512"
どうやら config/routes.rb
の 512 行目で定義されているらしい。その行を見てみる。
Rails.application.routes.draw do
# 略
resources :brands, only: %i(index show) do
resources :yoyos
end
# 略
resources :brands do # 512 行目
resources :bearings
end
end
resources :brands
が再度呼びだされていて、かつ only
オプションでのアクションの指定が無いせいで余計なルーティングが定義されてしまっていた。(本来は 1 つの resources :brands
にまとめるべきだが) 試しに、次のように only: %i(index show)
を指定してみる。
Rails.application.routes.draw do
# 略
resources :brands, only: %i(index show) do
resources :yoyos
end
# 略
resources :brands, only: %i(index show) do
resources :bearings
end
end
そうすると、余計なルーティングを削除することができた。
$ bin/rails routes --unused
No unused routes found.
おまけ: 未使用のルーティング一覧を取得する
bin/rails routes --unused
コマンドではなく Rails コンソールで未使用のルーティング一覧を取得することもできる。
require 'rails/commands/unused_routes/unused_routes_command'
routes = Rails.application.routes.routes
unused_routes = routes.select { Rails::Command::UnusedRoutesCommand::RouteInfo.new(it).unused? }
unused_routes.map { it.requirements.values_at(:controller, :action).join('#') }
#=> ["brands#create", "brands#new", "brands#edit", "brands#update", "brands#update", "brands#destroy"]
バージョン情報
RUBY_VERSION
#=> "3.4.1"
Rails.version
#=> "8.0.1
参考
Rails
Rails コンソール上でルーティングを検索したり参照したりする方法を調べるにあたり、以下の Ruby ファイルを参考にした。