update_attributes/update_columnsの違い

今日はupdate_attributes/update_columnsの違いについて説明します。

自分自身が違いを理解していなかったので、使い分けの理解ができていなかったです。

概要

下記の記事から引用させていただきます。

qiita.com

メソッド 保存 バリデーション(*1) コールバック(*2) readonly チェック(*3) updated_at の更新 補足 使用例
update_attributes o o o o o update の alias article.update_attributes(title: 'title', body: 'body')
update_columns o x x o x UPDATE SQL を発行して DB を更新するため最も速い。新しいオブジェクトの場合は例外が発生する。readonly の attribute が更新対象に含まれる場合は例外が発生する。 article.update_columns(title: 'title', body: 'body')

使い方

主な差はvalidationとcallbackになります。

たとえば、下記のようなPostモデルの内容にvalidationがあるとします。

class Post < ActiveRecord::Base
  validates :body, length: { maximum: 10 }
end

update_attributes

・validation内

irb(main):002:0> post.update_attributes(body: 'aaaaaaaaaa')
   (0.2ms)  BEGIN
  SQL (1.6ms)  UPDATE `posts` SET `body` = 'aaaaaaaaaa', `updated_at` = '2016-04-26 14:07:40' WHERE `posts`.`id` = 10001
   (0.6ms)  COMMIT
=> true

・validation外

irb(main):005:0> post.update_attributes(body: 'aaaaaaaaaaaaaa')
   (0.2ms)  BEGIN
   (0.1ms)  ROLLBACK
=> false

validationを意識してくれます。

update_columns ・validation内

irb(main):006:0> post.update_columns(body: 'aaaaaaaaaa')
  SQL (8.7ms)  UPDATE `posts` SET `posts`.`body` = 'aaaaaaaaaa' WHERE `posts`.`id` = 10001
=> true

・validation外

irb(main):007:0> post.update_columns(body: 'aaaaaaaaaaaaaaaaaaaa')
  SQL (8.7ms)  UPDATE `posts` SET `posts`.`body` = 'aaaaaaaaaaaaaaaaaaaa' WHERE `posts`.`id` = 10001
=> true

validationが無視されます

まとめ

update_columnsを使うときは、validationの判定を意識しないといけない。