Yanonoblog!

こつこつと

Railsにおけるupdate_allとupdateの違い

背景

一括更新機能の実装を行った際に軽く調べた内容を書き留めておきたいと思いました。

本記事では、一括更新時のupdateとupdate_allに関する説明を簡単に解説していきます。

概要

update_allメソッド

update_allは、Active Recordのクエリインターフェースを使用して、条件に一致するレコードを一括更新するためのメソッドです。

SQLのUPDATE文に相当するものであり、複数のレコードを一度に更新することができます。

以下はupdate_allを用いて投稿の公開非公開フラグを一括で更新する例です。

def bulk_update_is_published
  Post.update_all(is_published: params[:is_published] == "1")
end

メリット - 高速である

モデルのコールバックやupdated_atカラムを更新しないため、処理が高速です。

レコードを一括更新する際にSQL文1回で済むことも処理が高速になる要因の一つです。

特に今回のようなテーブルのカラムすべてを一括更新する内容だと処理が重くなるケースがあります。(あまりないですが)

作業的に何度も切り替えたりするようなフラグであれば動作性の恩恵があるupdate_allは良いと思いました。

デメリット - バリデーションやコールバックが行われない

update_allは、一括更新時にRails上のバリデーションやコールバックはまったく動作しません。

一般的なバリデーション機能、updated_atカラムも更新しないため、手動で更新する必要があります。

update_allは処理が高速でメモリ消費も少なく、大量のレコードを更新する場合には有効なメソッドですが、注意点もあるため適切に使用する必要があります。

updateメソッド

updateは、Active Recordのインスタンスメソッドとして提供されるレコードを更新するためのメソッドです。

eachで投稿の公開非公開フラグを繰り返し更新する例です。

  def bulk_update_is_activate
    Post.all.each do |post|
      post.update(is_published: params[:is_published] == "1")
    end
  end

メリット - データの整合性を保つことが出来る

バリデーションやコールバックが実行されるため、データの整合性を保つことができます。

エラーが発生した場合に更新が中断されます。一方でupdate_allは、エラーが発生しても更新が完了してしまいます。

デメリット - パフォーマンスの低下

メモリの使用量が増加するため、大量のレコードを更新する場合はパフォーマンスが低下します。

デメリット - 処理速度の低下

更新ごとにSQL文が実行されるため、update_allに比べて処理が遅くなる可能性があります。

まとめ

私の場合は作業的に更新を切り替えするカラムだったためupdate_allが適切と思いましたが、updated_atが更新されたほうが嬉しいとのことでしたため、update_allはやめてupdateを繰り返し実行するように実装しました。

  • 単純かつ大量の一括更新を作業的に行うような場合にupdate_allを使用する
  • コールバックやエラーなどを正確にハンドリングを行いたい場合はupdateを使用する
  • update_allでupdated_atも一括更新するでもよかったのでしょうか。あまり変わらないかもしれませんが。(笑)

    おわりに

    コメント

    本記事の内容は以上になります!

    参考になったり学びのきっかけになりますと幸いです。

    間違いがありましたら修正いたしますので、ご指摘ください。

    興味があれば他の記事も更新していきますので是非ご覧になってください♪


    プログラミングスクールのご紹介 (卒業生より)

    お世話になったプログラミングスクールであるRUNTEQです♪

    https://runteq.jp/r/ohtFwbjW

    こちらのリンクを経由すると1万円引きになります。

    RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

    もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

    https://twitter.com/outputky