12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ソニックガーデン プログラマAdvent Calendar 2024

Day 24

routes.rbでちょっと便利なresolveメソッド

Last updated at Posted at 2024-12-23

Railsのroutes.rbで使用できるresolveメソッドについて紹介します。resolveメソッドは、polymorphic_pathpolymorphic_urlにモデルインスタンスを渡した際に生成されるURLをカスタマイズできます。

resolveとは

Railsのビューヘルパーでは、link_to 'title', @postのように、URLが必要とされる箇所でモデルインスタンスを直接渡すことができます。このとき、内部ではpolymorphic_pathによってURLが生成されています。resolveを使用することで、この生成されるURLを柔軟に変更することが可能になります。

polymorphic_pathの挙動

polymorphic_pathには、主にモデルインスタンスやシンボル、またはそれらの配列を渡すことができます。

  • モデルインスタンスの場合: persisted?(データベースに保存済みかどうか)によって、単数形(モデルインスタンスの引数つき)または複数形のURLヘルパーが使用されます。例えば、@postが保存済みであればpost_path(@post)、未保存であればposts_pathが使用されます。
  • シンボルの場合: そのシンボル名に対応するURLヘルパーが使用されます。例えば、:basketであればbasket_pathが使用されます。
  • 配列の場合: 配列の先頭から順に、中身に応じて名前を_で連結したURLヘルパーが組み立てられます。モデルインスタンスとシンボルが混在している場合も、上記ルールに従って処理されます(詳細は後述)。

単数リソースにおけるresolveの活用

単数リソース(例えば、resource :basket)の場合、form_with model: @basket do |f|のように記述すると、内部でpolymorphic_path(@basket)が実行され、通常はbasket_path(@basket)が呼ばれ、URLは/baskets/:idとなります。しかし、単数リソースでは/basketというURLを期待する場合が多いです。

このような場合に、resolveが役立ちます。以下のように定義することで、polymorphic_path(@basket)polymorphic_path([:basket])と同様に扱われるようになります1

resolve "Basket" do
  [:basket]
end

この定義により、polymorphic_path(@basket)の内部でこの定義が参照され、シンボル:basketからbasket_pathが組み立てられ(引数なし)、URLは/basketとなります。

URLの配列記法とネストされたリソース

polymorphic_pathには配列を渡すことができ、これはネストされたリソースや名前空間内のリソースを指す際に便利です。

  • polymorphic_path([@post, @comment])post_comment_path(@post, @comment)に相当します。
  • polymorphic_path([:admin, @post])admin_post_path(@post)に相当します。

ネストされたリソースの場合、resolveを使って子リソースのインスタンスのみからネストされたURLを生成することができます。

resolve "Comment" do |comment|
  [comment.post, comment]
end

この定義により、polymorphic_path(@comment)/posts/:post_id/comments/:idというURLを生成するようになります。これにより、link_to "コメント", @commentのように簡潔に記述することができます。

まとめ

resolveの利用法として単数リソースのURLを調整したり、ネストされたリソースのURLを簡略化する例を挙げましたが、他にももっと複雑なURLのルールを作るときにも便利です。活用してみましょう!

References

  1. 要素が1つだけなので配列[:basket]ではなく単に:basketでも問題ありませんが、Railsガイドやリファレンスマニュアルでは配列で記述されていることが多いため、ここではそれに倣っています。また、実際の動作はpolymorphic_url([:basket])が呼ばれた後、パス部分だけが抜き出されます。

12
2
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
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?