Rails: ルーティングを'only'や'except'オプションで整理する(翻訳)
Railsのルーティング定義構文をそのまま使ってルーティングを書いていると、アプリケーションで使うつもりのURLよりも多くのURLが生成されてしまいがちです。
以下のように書くよりも
ルーティングで制約なしのresources
ブロックを使う。
resources :orders do
resources :products
end
以下のように書こう
生成するルーティングをonly
オプションやexcept
オプションで制限する。
resources :orders, except: %w[destroy] do
resources :products, only: %w[show]
end
そうする理由
これは、ルーティングを明確にして整理し、予期しないエラーやセキュリティホールを防ぐためのものです。
デフォルトの制限なしルーティングの場合、7種類のデフォルトルーティングがすべて作成されます。定義されているが使われていないルーティングにユーザーがアクセスすると、該当するコントローラにアクションが存在しない場合でもアクションを呼び出そうとします。これによってエラーが発生したり、場合によっては予期しない振る舞いにつながる可能性もあります。
Rails標準の命名規則は、コードを整理して構造化する優れた方法ですが、ルーティングが外部ユーザーから推測可能になるということでもあります。orders#show
を呼び出すGET /orders/12345
というルーティングが存在すれば、そこからorders#index
を呼び出すGET /orders
ルーティングや、もっと危険なorders#update
を呼び出すPUT /orders/12345
ルーティングの存在も推測されるかもしれません。
生成されるルーティングを最小限にとどめる作業は、コードベースを安全な形で整理する作業の1つでもあります。
極端に大規模なコードベースには、この問題を抱えたルーティングが多数あるので、ルーティングの生成数を減らすことでパフォーマンス向上を見込めるかもしれません。しかしそこまで考える必要が生じるのは、よほど大規模なアプリケーションの場合でしょう。
そうしない理由があるとすれば
これはアプリケーションで必ずしも深刻な問題になるとは限りません。config/routes.rb
ファイルに目を通しておく価値はありますが、あくまでコードを整理するうえでのメリットです。
概要
元サイトの許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。
参考: § 4.6 作成されるルーティングを制限する -- Rails のルーティング - Railsガイド
なお、RailsのルーティングはCLIで
bin/rails routes
で表示できます。また、Rails 7.1では、
--grep
でルーティング表示をフィルタする機能が入る予定です(#45874)Railsのルーティングをビジュアル表示する方法については、以下の記事もどうぞ。