[解決済み] ネストされたリソースを持つ form_for
質問
form_forとネストされたリソースについて、2つのパートからなる質問があります。例えば、私がブログエンジンを書いていて、コメントを記事に関連づけたいとします。私は以下のようにネストされたリソースを定義しました。
map.resources :articles do |articles|
articles.resources :comments
end
コメントフォームは、記事用のshow.html.erbのビューで、記事自体の下に、例えばこのようにあります。
<%= render :partial => "articles/article" %>
<% form_for([ :article, @comment]) do |f| %>
<%= f.text_area :text %>
<%= submit_tag "Submit" %>
<% end %>
これは、 "Called id for nil, which would mistakenly etc." というエラーを出します。
<% form_for @article, @comment do |f| %>
これは正しく表示されますが、f.text_areaをコメントではなく記事の'text'フィールドに関連付け、そのテキストエリアにarticle.text属性用のhtmlを表示します。というわけで、これも間違っているようです。私が欲しいのは、commentsController の create アクションを呼び出すフォームの 'submit' で、params に article_id を指定し、例えば /articles/1/comments に post リクエストをするものです。
質問の第二は、そもそもコメントインスタンスを作成するのに最適な方法は何なのかということです。私はArticlesControllerのshowアクションで@commentを作成し、コメントオブジェクトがform_forヘルパーのスコープになるようにしています。それから CommentsController の create アクションで、form_for から渡されたパラメータを使用して新しい @comment を作成します。
ありがとうございます!
どのように解決するのですか?
Travis Rは正しいです。(upvoteできればいいのですが。) 私はちょうどこれを自分で動かすことができました。これらのルートで。
resources :articles do
resources :comments
end
のようなパスが得られます。
/articles/42
/articles/42/comments/99
にあるコントローラにルーティングされます。
app/controllers/articles_controller.rb
app/controllers/comments_controller.rb
に書いてあるように http://guides.rubyonrails.org/routing.html#nested-resources で、特別な名前空間はありません。
しかし、部分とフォームが厄介なことになります。角括弧に注意してください。
<%= form_for [@article, @comment] do |f| %>
最も重要なのは、URIが必要な場合、このようなものが必要な場合があります。
article_comment_path(@article, @comment)
あるいは
[@article, @comment]
で説明したように http://edgeguides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects
例えば、コレクションパーシャルの内部で
comment_item
が繰り返しのために提供されています。
<%= link_to "delete", article_comment_path(@article, comment_item),
:method => :delete, :confirm => "Really?" %>
jamuraaさんのおっしゃることは、Articleの文脈では有効かもしれませんが、他の様々な点では私にはうまくいきませんでした。
ネストされたリソースに関連する多くの議論があります、例えば http://weblog.jamisbuck.org/2007/2/5/nesting-resources
興味深いことに、ほとんどの人のユニットテストは、実際にはすべてのパスをテストしていないことを知りました。jamisbuck 氏の提案に従うと、ネストされたリソースを取得する 2 つの方法で終わります。ユニットテストは一般に、最も単純なものを取得/投稿します。
# POST /comments
post :create, :comment => {:article_id=>42, ...}
彼らが好むかもしれないルートをテストするために、このようにする必要があります。
# POST /articles/42/comments
post :create, :article_id => 42, :comment => {...}
これを切り替えたらユニットテストが失敗するようになったので覚えました。
resources :comments
resources :articles do
resources :comments
end
をこれに変更します。
resources :comments, :only => [:destroy, :show, :edit, :update]
resources :articles do
resources :comments, :only => [:create, :index, :new]
end
ルートが重複していても、ユニットテストが少なくても大丈夫なんでしょうね。(なぜテストするのでしょうか?なぜなら、ユーザーが重複を見ることがなくても、フォームが暗黙のうちに、もしくは名前つきのルートを通して、それらを参照する可能性があるからです)。それでも、不要な重複を最小限にするために、私はこれを推奨します。
resources :comments
resources :articles do
resources :comments, :only => [:create, :index, :new]
end
長い回答で申し訳ありません。微妙に意識している人は少ないと思います。
関連
-
[解決済み】Webpacker::Manifest::MissingEntryError【クローズド
-
[解決済み] nil:NilClass の未定義メソッド `each'... なぜでしょうか?
-
[解決済み] erbでコメントを追加する最適な方法
-
[解決済み] nil:NilClass の未定義メソッド `each'... なぜ?
-
[解決済み] Railsです。gemを使った特定バージョンのライブラリのアンインストール
-
[解決済み] Ruby:Rubyの配列にinclude.の反対はある?
-
[解決済み] Ruby: public static メソッドを作るには?
-
[解決済み] Rails / Haml: 投稿フォームを作成するには?
-
[解決済み] RSpecとCucumberの違いは何ですか?[クローズド]
-
[解決済み] 属性とカラムの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】gemのインストールができない - gemネイティブ拡張の構築に失敗 - そのようなファイルをロードできない -- mkmf (LoadError)
-
[解決済み] heroku open - no app specified
-
[解決済み] 変更欄のRailsマイグレーション
-
[解決済み] erbでコメントを追加する最適な方法
-
[解決済み] rspec 3 - クラスメソッドをスタブ化する
-
[解決済み] rails erb フォームヘルパー options_for_select :selected
-
[解決済み] Ruby:Rubyの配列にinclude.の反対はある?
-
[解決済み] Devise Admin Roleの追加【終了しました
-
[解決済み] railsで':remote => true'はどのように動作するのでしょうか?
-
[解決済み] RSpecとCucumberの違いは何ですか?[クローズド]