Asarluhi
Asarluhi

Reputation: 1290

How to delete a collection matching a condition

I would like to delete all posts associated to every user of my application matching a determined condition. In particular I would like to delete all posts older than 30 days only if a user has more than 20 posts. At first I wrote the following code:

users = User.all
users.each do |user|
    if user.posts.any? && user.posts.count > 20
        user.posts.delete_all('created_at < ?', 30.days.ago)
    end 
end

However, looking at the API documentation, method delete_all for collections does not imply the records are actually removed from the database, and that depends precisely on the specified parameter, :nullify or :delete_all

Therefore, considering that method delete_all for collections requires one of the above parameters, would the following code be correct:

users = User.all
users.each do |user|
    if user.posts.any? && user.posts.count > 20
        user.posts.where('created_at < ?', 30.days.ago).delete_all(:delete_all)
    end 
end

or am I expected to use something different?

Upvotes: 1

Views: 67

Answers (1)

Mihai Dinculescu
Mihai Dinculescu

Reputation: 20033

You need to explicitly specify the :delete_all flag only when you define your association with the :nullify flag.

class Post < ApplicationRecord
  belongs_to :user, dependent: :nullify
end

Otherwise :delete_all is implied.

One other important point is that delete_all ignores the callbacks that you might have defined. If you want to have the callbacks called, you need to use destroy_all.

destroy_all doesn't care about the dependent flag.

Upvotes: 1

Related Questions