Rails fields_for と accepts_nested_attributes_for を使うときの注意点

はじめに

Rails を使用して、何か作成するとき、必ずと言っていいほど、ネストしたフォームを作成することになる。しかしながら、毎回同じ場所で詰まってしまい、解決にかける時間がもったいなかったので、押さえるべきポイントを自分のメモがわりに残しておきたいと思った。

この記事ではfields_for と accepts_nested_attributes_for を使ったフォーム作成手順を1から100まで順を追って解説する記事ではありません。あくまでポイントだけを抑えたものとなってます。あらかじめご理解いただきたいです。

前提

今回の場合は 親モデル: post 子モデル: text_contents という関連を前提としています。 皆さんそれぞれの環境で親モデルと子モデルを当てはめて読んでくださいね。

気をつけるべきポイント

今回ハマった点

  1. accepts_nested_attributes_for を使用したら、フォームが表示されない
  2. controller に送信されたパラメータが ~~_attributes の形をしていない

これらの2点について解説していきたいと思います。

1. accepts_nested_attributes_for を使用したら、フォームが表示されない

これは、fields_forを使用した時に子モデルのインスタンスを生成していないために起こりました。 そのため、fields_for の第2引数に子モデルのインスタンスを渡してあげると良いでしょう。

before

<%= f.fields_for :text_contents do |text_contents_form| %>

after

<%= f.fields_for :text_contents, @post.text_contents.build do |text_contents_form| %>

2. controller に送信されたパラメータが ~~_attributes の形をしていない

こちらは皆さんもよく経験するのではないでしょうか? エラーも特に吐かないので苦労された経験がある方も多いと思います。

これが起こったとき確認すべきポイントを下に列挙していきます。

1. Association を確認する

まずはじめに、アソシエーションを確認しましょう。 親モデル・子モデルともにアソシエーションが定義されているか確認すると良いでしょう。 特に typo がないかは念入りにチェックすべきです。

2. accepts_nested_attributes_for の記述にミスはないか

親モデルにきちんと accepts_nested_attributes_for の記述があること。また、その記述が正しいことを確認しましょう。

3. fields_for の引数に渡す値が間違っている

今回はこれでした。まず、どの点が間違っていたのか下に例を載せます。

before

      <%= f.fields_for :contents, @post.text_contents.build do |text_contents_form| %>

after

      <%= f.fields_for :text_contents, @post.text_contents.build do |text_contents_form| %>

見ての通り、第一引数が contents になってしまっていました。 この引数が accepts_nested_attributes_for で定義した値と一致していることを確認しましょう

最後に

この記事はあくまで一例です。また使用するときに違う状況が再現したら追記していこうと思います。 また、コメントなどで、こちらの記事に違う再現状況などを教えてくださるとありがたいです。

Rails 初心者に届け...