Often we need to find records based on certain conditions and then delete those records. To perform this, ActiveRecord has introduced delete_by and destroy_by methods with Rails 6.

Let’s say, we have a following model.

class Post < ApplicationRecord {
:id => :integer,
:user_id => :integer,
:title => :string,
:description => :text,
:status => :string,
:created_at => :datetime,
:updated_at => :datetime
}

Requirement: Delete all posts created by a user with ID 5.

Before Rails 6

This can be done by using delete_all as given below.

Post.where(user_id: 5).delete_all Similarly, if we want to destroy all records, we can use destroy_all as given below.

Post.where(user_id: 5).destroy_all

The difference between delete_all and destroy_all is that, delete_all does not run callbacks defined over the corresponding model.

After Rails 6

As this feature of querying records based on some conditions and then deleting / destroying is required quite often, Rails 6 introduces delete_by and destroy_by methods.

Delete records by condition

Post.delete_by(user_id: 5)

Destroy records by condition

Post.destroy_by(user_id: 5)

It can also be used with associations as given below. Let’s say, we want to delete all posts of user with id 5 having status unpublished.

User.where(id: 5).posts.delete_by(status: 'unpublished')

Conclusion

As you can observe, delete_by / destroy_by, these are just short-hands for operations where(condition).delete_all and where(condition).destroy_all respectively.

Tags:RailsActiveRecord

...

Akshay Mohite

Akshay is a Ruby on Rails and ReactJS enthusiast. He likes to write blog posts. Contributes to open source whenever gets some free time.