LoginSignup
784
689

More than 5 years have passed since last update.

ActiveRecord の attribute 更新方法まとめ

Last updated at Posted at 2015-01-18

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。


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

784
689
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
784
689