Help us understand the problem. What is going on with this article?

ActiveRecord の attribute 更新方法まとめ

More than 3 years have passed since last update.

ActiveRecord の attribute 更新方法ってどんなものがあって、それぞれどんな違いがあるかご存じですか?

案外色々とあったので表にまとめてみました。リファレンスやソースコードを参考にしつつ、Rails 4.2 でテストしています。

単一の attribute 更新

メソッド 保存 バリデーション(*1) コールバック(*2) readonly チェック(*3) updated_at の更新 補足 使用例
attribute= x - - - - article.title = 'title'
write_attribute x - - - - private メソッド。attribute= はこれを呼び出している。タイプキャストを行う。例えば integer なカラムの attribute に "5" を渡すと数値の 5 に変換する。 write_attribute(:title, 'title') write_attribute(:rate, "5")
self[:attribute] x - - - - write_attribute の alias。こちらは public。 article[:title] = 'title'
raw_write_attribute x - - - - private メソッド。渡された値のタイプキャストを行わない。例えば integer なカラムの attribute に "5"を渡しても数値の 5 に変換しない。 raw_write_attribute(:title, 'title'), raw_write_attribute(:rate, "5")
update_attribute o x o o o dirty な attribute をすべて保存する。readonly な attribute の場合は例外が発生する。 article.update_attribute(:title, 'title')
update_column o x x o x update_columns(name => value) に相当。詳細については次の表へ。 article.update_column(:title, 'title')

複数の attribute をまとめて更新

メソッド 保存 バリデーション(*1) コールバック(*2) readonly チェック(*3) updated_at の更新 補足 使用例
assign_attributes x - - - - article.assign_attributes(title: 'title', body: 'body')
attributes= x - - - - assign_attributes の alias article.attributes = { title: 'title', body: 'body' }
update o o o o o save を呼び出す article.update(title: 'title', body: 'body')
update_attributes o o o o o update の alias article.update_attributes(title: 'title', body: 'body')
update! o o o o o update と同じ処理を行うが、save ではなく save! を呼び出す。そのため例外が発生する。 article.update!(title: 'title', body: 'body')
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')

クラスメソッド

メソッド 保存 バリデーション(*1) コールバック(*2) readonly チェック(*3) updated_at の更新 補足 使用例
update o o o o o readonly な attribute を指定すると無視される Article.update([1, 2], [{ title: 'title1', body: 'body1' }, { title: 'title2', body: 'body2' }])
update_all o x x x x 対象のリレーション中すべてのレコードに対して UPDATE SQL を発行する。ActiveRecord のインスタンスを作成しないためバリデーションやコールバックの呼び出し、タイプキャストなどは行われない。そのため、そのまま DB に保存して良い値しか渡すべきではない。 Article.where(category: 'rails').update_all(title: 'title', body: 'body')

(1) 保存時にバリデーションが行われるかどうか。
(*2) 保存時に各種コールバックが呼び出されるかどうか。
(
3) attr_readonly で指定した readonly な attribute が更新されない場合は o。される場合は x。


何かミスにお気づきの際はコメントしていただけると助かります。

tyamagu2
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした