Rails 7.1: url_for
ヘルパーにpath_params
オプションが追加(翻訳)
Rails 7.1のurl_for
ヘルパーで、path_params
という新しいオプションがサポートされました。
Rails 7.1より前は、ルーティングで以下で示すようにscope
でたとえばuser_id
を指定している場合、このスコープ付きルーティングのリンクを生成するすべての場所で(ビューファイルを書くときなど)、user_id
を明示的に指定しなければなりませんでした。
#routes.rb
Rails.application.routes.draw do
root "articles#index"
scope ":user_id" do
get "/articles", to: "articles#index"
get "/articles/:id", to: "articles#show"
end
get "/categories", to: "categories#index"
end
<!-- app/views/articles/index.html.erb -->
<a href="<%= articles_path(user_id: @current_user.id) %>"> Articles </a>
これは、ApplicationControllerを更新してdefault_url_options
メソッドを上書きすれば一応解決できます。
# application_controller.rb
class ApplicationController < ActionController::Base
def default_url_options
{ user_id: "unique-id" }
end
end
このdefault_url_options
メソッドは、url_for
に基づくすべてのメソッドについてデフォルトオプションを上書きするのに使われます。ただしこれを行うと、user_id
スコープに属していないルーティングも含め、すべてのルーティングの末尾に?user_id=unique-id
クエリパラメータが追加されてしまい、結果は以下のようになります。
articles_path # => /unique-id/articles
categories_path # => /categories?user_id=unique-id
Rails 7.1では、url_for
にpath_params
オプションを追加することでこの問題を修正しました。パラメータのハッシュをキーに渡すと、それらのパラメータはルーティングの名前付きセグメントでのみ使われるようになります。パラメータが使われない場合は破棄されるので、クエリパラメータとしてルーティングの末尾に追加されることはありません。
この変更によって、default_url_options
メソッドを以下のように実装できるようになります。
class ApplicationController < ActionController::Base
def default_url_options
{ path_params: { user_id: "unique-id" } }
end
end
url_for
ヘルパーメソッドによって、以下の出力が得られます。
articles_path # => /unique-id/articles
articles_path(user_id: "test-id") # => /test-id/articles
categories_path # => /categories
categories_path(user_id: "test-id") # => /categories
これで、ビューで以下のようにuser_id
を書かずに済むようになります。
<a href="<%= articles_path %>"> Articles </a>
これは、他のルーティングに不要なクエリパラメータを追加せずに、ルーティングURLの一部として必須パラメータだけを追加したい場合に非常に便利です。
詳しくは#43770を参照してください。
概要
元サイトの許諾を得て翻訳・公開いたします。
参考: 週刊Railsウォッチ20230621:
url_for
ヘルパーに新しいpath_params
オプションが追加