QA@IT

Nested Resourcesで生成されるURLヘルパーの引数を1つにしたい

2490 PV

概要

Nested Resourcesで生成されるURLヘルパーの引数複数個を1つに纏めたいと思っています。以下が詳細になります。ご助言頂けると嬉しいです。

前提

まず現在の状況をご説明します。Rails 3.2.13でUserモデルとItemモデルをScaffoldで作成しました。最小限のテーブル定義は以下になり、Itemオブジェクトは必ずただ一つのUserオブジェクトにひも付きます。

    create_table :users do |t|
      # None
    end

    create_table :items do |t|
      t.integer :user_id, null: false
    end

ここでURLヘルパーを定義するため、以下の様な記述をroutes.rbにしています。

  resources :users, only: :show, path: :u do
    resources :items, only: :show, path: ''
  end

質問

そこで生成されるURLヘルパー"user_item_path(@user, @item)"の2つの引数を1つに纏めたいというのが今回の質問です。今回のモデル構成だと、Itemオブジェクトは必ずUserオブジェクト1つに結びつくので、@itemという引数さえ分かれば@userは自明のはずです。ですので前述のURLヘルパーを"user_item_path(@item)"としたいです。どのようにすればこのような形にURLヘルパーを修正できるでしょうか?

試行

今はApplicationHelperでURLヘルパーをオーバーライドして実現しているのですが、汚く可読性が落ちるのでこれを解消したいと思い、この質問をさせて頂きました。そもそもネストしなければ引数は一つになるのですが、個別アイテムのURLを削ることで個別ユーザのURLになるようにしたいと思っているので、廃案となりました。

何卒よろしくお願い致します。

回答

試行に書かれているとおり URLヘルパーをオーバーライドするのを時々利用しています。

規約からはずれてしまい直感的ではないと感じるのであれば user_item_path をオーバライドではなく item_path を定義したり、工夫した名前にするぐらいだと思います。
form_forlink_to などでリンク先に [@user, @item] とした時にも user_item_path が利用されますが、この時に @item にすると item_pathになるので、楽ができそうな気がします。
(別の問題が発生する可能性も出てきそうですが)

今回のモデル構成だと、Itemオブジェクトは必ずUserオブジェクト1つに結びつくので、@itemという引数さえ分かれば@userは自明のはずです。

構成上では自明ですが、ルーティングはモデルの情報を利用しないので、Railsからすると自明ではないと思います。特定の規約に合わせているので偶然動くのに過ぎません。
ルーティングを工夫すればなんとかする方法があるかも知れませんが、ヘルパーをオーバーライドする観点で回答してみました。

編集 履歴 (0)
  • なるほど納得しました。確かにitem_pathとした方が既存のものと整合性が取れますね。
    > ルーティングはモデルの情報を利用しないので、Railsからすると自明ではない
    しっくりきました。ありがとうございます!
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。