Category : Ruby

※ 20140307 一部追記修正しました
new/create時に関連テーブルも更新する記述について、忘れていたのでまとめてみました。
(意外と参考書とかにも載っておらず・・・)
今回利用しているバージョンは下記。

  • Ruby -> 2.1.0
  • rails -> 4.0.2

やりたいこと

20140225_rails_view

こんなイメージです。postを1件更新するときに関連テーブル(authors)と中間テーブル(author_posts)を複数件数一気に更新する感じです。

Model

  • いつものhas_many through
  • posts <-> author_posts <-> authors
  • authorsは “name” カラムを持つ
  • formでネストさせるので、accepts_nested_attributes_for も設定します

まずはirbで動作を確認

関連オブジェクトの値を更新する際は、post.authors.build のようにする必要があります。
複数個の場合は複数回buildしてあげればよさそうです。
上記を元に、View、Controllerを作っていきます。

View(フォーム)


“authors_attributes[]”の部分は、普通は:authorsと書くようですが・・・
複数個更新するときには上記のように書くと、同名のパラメータを配列に格納してくれます。
また、authorsのnameカラムを更新したいので、text_fieldには :name と記述します。

追記):authors でも動作しました。

ポストされるパラメータ
params[:post][:authors_attributes]の中身は下記になります。

(実験)f.fields_forの引数を :authors にした場合のパラメータ


keyに個数を表す数値が入ってきてしまいました。
これが気持ち悪くて配列で取得するようにしています。

追記)ハッシュ形式の方が正しいようです。

Controller


本当はcreateに何も追記したくなかったのですが・・・(これ以外の方法がわかりませんでした。)
また、strong parametersのホワイトリストに :authors_attributes => [] を追記しています。

追記)上記のようにstrong parametersに記述をすることで、余計な処理を書かずに更新出来ました。
ただし、データを取り出して何らかの加工をする場合には、Arrayで取得しても良さそうです。

参考