💡

polymorphic_pathを使えば、複雑な「xxx_path」を簡潔に書ける

2025/01/28に公開

何が嬉しいか

「記事」や「コメント」などのデータを、複数のモデル(例えば「一般ユーザー」と「管理者ユーザー」)が操作できるとき、どのモデル経由かを意識せずにURLを作成できる。
その結果、xxx_xxx_xxx_path のような長くて複雑なヘルパーを使わずに済む。

例えば「記事」に対して「一般ユーザー」と「管理者ユーザー」が「コメント」を付けることができるようなケース

resources :articles do
  resources :comments
end

namespace :admin do
  resources :articles do
    resources :comments
  end
end

以下のように、_path ヘルパーが利用可能になります。

管理者ユーザーが記事に対するコメントを操作する際

# 一覧表示
admin_article_comments_path(@article)
# 作成時
new_admin_article_comment_path(@article)
# 編集時
edit_admin_article_comment_path(@article, @comment)

一般ユーザーが記事に対するコメントを操作する際

# 一覧表示
article_comments_path(@article)
# 作成時
new_article_comment_path(@article)
# 編集時
edit_article_comment_path(@article, @comment)

しかし、ネストが深くなったりするとヘルパー名が長くなり、複雑なものになってしまいます。どうにかならないかと思っていたところ、ヘルパー名を気にせずに書く方法があることを知りました。それが polymorphic_path を使った書き方です。

polymorphic_pathを使う場合

polymorphic_pathを使用すると、以下のようにヘルパー名がシンプルになります。

管理者ユーザーが記事に対するコメントを操作する際のパス生成

# 一覧表示
polymorphic_path([:admin, @article, :comments])  

# 作成時
new_polymorphic_path([:admin, @article, :comment])

# 編集時
edit_polymorphic_path([:admin, @article, @comment])

一般ユーザーが記事に対するコメントを操作する際のパス生成

# 一覧表示
polymorphic_path([@article, :comments])

# 作成時
new_polymorphic_path([@article, :comment])

# 編集時
edit_polymorphic_path([@article, @comment])

便利ですね。
ちなみに、_urlヘルパーを使用したい場合にはpolymorphic_urlを使えます。

公式ドキュメント
https://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html

Discussion