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.