Rails 6 adds delete_by and destroy_by methods on ActiveRecord

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')


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.

Leave a Comment

Your email address will not be published. Required fields are marked *