カテゴリー:
Rails
タグ:
 Rails 配列 更新 update model ActiveRecord update_all

このエントリーをはてなブックマークに追加
更新日時:
2013年11月03日(日)
作成日時:
2013年11月03日(日)

前の記事 / 次の記事

参考: 複数レコードの一括更新

Railsでオブジェクトを更新するとき。

@object.update(params[:object])

ってできるけど、配列の時は?

@objects.update(ids, attributes)
# バリデーションを通る
# ids は更新したいオブジェクトの id の配列
# attributes は更新したいオブジェクトの属性と値のペアのハッシュ

もしくは

@objects.update_all(attributes)
# バリデーションを通らない(他のコールバックも走らないのでその分高速)
# attributes は更新したいオブジェクトの属性と値のペアのハッシュ

で更新できる。具体的には次のように書ける。
例えば特定の属性を全てブランクにして保存したい場合。

ids        = @objects.ids
attributes = Array.new(ids.size, { name: "" })
@objects.update(ids, attributes)

もしくは

@objects.update_all(name: "")

前者の方法(update)ではバリデーションは通るけど、
バリデーションを通過できたかどうかは個別のオブジェクトを調べないと分からない。
つまり、

if @objects.update(ids, attributes)
  redirect_to object_path
else
  render action: :edit
end

みたいに書いても必ず真ルートに分岐するので、
こういうことをしたい場合は、

if @objects.all? { |object| !object.errors.any? }
  redirect_to object_path
else
  render action: :edit
end

とか、もうひと頑張り必要。

で、後者の方法(update_all)ではバリデーションは通らないけど、
そもそも一括更新したいような場合ってバリデーションを考慮しなくていい場合が
多い気がするので、後者の出番の方が多いのかなと。