update
goes via the ActiveRecord record, while update_all
writes to the column in SQL.
by Adam Dawkins
update
will do Rails magic, such as allowing a model to be passed to it:
Post.find_each {|post| post.update(category: nil)}
Rails runs:
UPDATE posts SET category_id = NULL WHERE posts.id = #{post.id}
But with:
Post.update_all(category: nil)
Rails tries to run:
UPDATE posts SET category = NULL
Which errors, because category
isn’t a column.
.update_all
should be used very sparingly, but where it is used (e.g. in a data migration), you need to refer to table columns, not record attributes.