So #update_all Is A Thing

ActiveRecord's update_all Method

Usecase

Imagine we need to make a similar change to a large group of database records. For example, let's say I have an application with a Students model. Let's also imagine that their is a status attribute on our Students model that can be incoming, active, disenrolled, or graduate. Summer has arrived and it is time to update the status of all of our students who have graduated.

Where + Loop

One way to change our students' statuses from active to graduate would be to query the database for students in the graduating cohort, looping over each student, and changing the status attribute accordingly.

The above process would look something like this:

Student.where(cohort: "2017").each do |student|
  student.status = "graduate"
  student.save!
end

If I have an app that manages a few hundred or thousand students, the above code will be fine. There is one read from the database to pull all the students and then one write to the database per student. But what if I have millions of students in my application?

update_all

Update_all will, as the name suggests, update a set of records at one time. Instead of the above one read and N writes to the database, we would only have one read and one bulk write. 

Student.where(cohort: "2017").update_all(status: "graduate")

One caveat with update_all is that this method will not change the updated_at field of the records it updates, so we could amend the above code to be:

Student.where(cohort: "2017").update_all(status: "graduate", updated_at: Time.now)

I hope this helps you optimize your own database updates!