Rahul Ojha
Rahul Ojha

Reputation: 416

Mass/bulk update in rails without using update_all with a single query?

I want to update multiple rows using single query of active record. I don't have to use update_all because it skips validation. Is there any way to do this in rails active record.?

Upvotes: 8

Views: 29399

Answers (3)

Abdul Basit Mangat
Abdul Basit Mangat

Reputation: 1180

Mass update without using update_all can be achievable using activerecord-import gem. Please refer to this gem for more information. Methods with detail.

Example: Lets say there is a table named "Services" having a "booked" column. We want to update its value using the gem outside the loop.

services.each do |service| 
 service.booked = false 
 service.updated_at = DateTime.current if service.changed?
end


ProvidedService.import services.to_ary, on_duplicate_key_update: { columns: %i[booked updated_at] }

active-record import by default does not update the "updated_at" column. So we've to explicitly update it.

Upvotes: 4

Alex Grin
Alex Grin

Reputation: 3183

If you want to update multiple records without instantiating the models, update_all method should do the trick:

Updates all records in the current relation with details given. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. However, values passed to #update_all will still go through Active Record’s normal type casting and serialization.

E.g:

# Update all books with 'Rails' in their title
Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')

As I understood, it even accepts an array as a parameter, allowing us to provide different hashes to update different records in their corresponding order, like in SQL UPDATE statement. Correct me, somebody, if I'm wrong.

Upvotes: 7

Mayur Shah
Mayur Shah

Reputation: 3449

It sounds like you are looking for Update records - from the documentation Updating multiple records; different col with different data

You can do like this Example:

people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)

Upvotes: -7

Related Questions