Ruby on Rails resources定義をネストするとform_forの相性が悪い

こんな感じでルーティング定義されたtweetのフォームを作成する時に、form_forメソッドでフォームを作成しようとすると、例外が発生してしまう。

ので、その原因と対策を紹介(自分のメモレベル?)しよう。

前提

モデルの関係

 

ルーティングの設定

tweetフォームをform_forで作成するとエラーになる

上述した、resourceでネストされたモデルに対して、通常のRESTfulなモデルと同じようにフォームを作成すると、newやeditアクションなどで、_form.html.erbにアクセスした時に例外が発生する。

scaffoldで作成されるデフォルトのフォーム

 

http://localhost:3000/users/980190962/tweets/new にアクセスすると、例外が発生。

undefined method `tweets_path' for #<#<Class:0x4b6a890>:0x4c32a38>

 

原因はメッセージ通りで、tweetのルーティング宣言は

としていることで、tweets_pathのヘルパは存在しないよというもの。

代わりにuser_tweets_pathヘルパが作成されている。

 

こういったネストされたRESTfulなリソースに対してform_forしたいときは、モデルインスタンスの指定だけではなく、urlを明示的に指定しないといけないようだ。

 
 

2013/01/06 追記:

resource定義がネストされたRESTfulなリソースに対してform_forを使う場合は、こう記載するのがrails wayなやりかただった。

form_forヘルパに、親リソースのモデルと子リソースのモデルからなる配列を渡す。
これで、:urlパラメータを明示的に指定していた場合と同じ結果になる。

ActionView::Helpers::FormHelper.form_forにちゃんと記載があった。

コメントを残す

トラックバック: http://pgnote.net/wp-trackback.php?p=1372