user1885058
user1885058

Reputation: 599

DELETE FROM table WHERE myfield = 1 (ActiveRecord)

I'm having a problem figuring out how to quickly destroy thousands of records.

I have a model called ITEM. It:

has_many :pictures (up_to 20)
has_many :ads (up to 10)
has_many :views (up_to 5000-8000)
has_many :posts (up to 100-200)

When user destroys his item - all children need to be gone as well.

So I tried everything I could find, but all solutions make queries based on ID:

:dependant => :destroy // makes a query per each item
***
before_destroy :destroy_children
private
def destroy_children
 pictures.delete_all
 ads.destroy_all
 views.destroy_all
 posts.destroy_all
end
// same

My current solution looks like this:

class Item << ActiveRecord:Base
has_many :pictures, :dependent => :destroy

before_destroy :destroy_children

private
def destroy_children
 pictures.destroy_all
 Ad.delete(self.ads.collect{|x| x.id})
 Post.delete(self.ads.collect{|x| x.id})
 View.delete(self.ads.collect{|x| x.id})
end

end

Basically, it gets an array of ID's of all Views that belong to item, and then makes a big IN statement like this:

DELETE FROM Views WHERE id IN (2, 3, 6, 8, 35, 50...)

This is still too heavy if my IN array has say a couple thousand ID's.

Is there a way to generate this query?

DELETE FROM Views WHERE item_id = 4

Maybe something like this?

View.delete(:item_id => 2)
// it doesn't work, but maybe something like this exists

It's wierd that I couldn't find anything like this anywhere.

Upvotes: 0

Views: 62

Answers (1)

Khaled
Khaled

Reputation: 2091

You could be doing the following:

private
def destroy_children
  pictures.destroy_all
  Ad.delete_all(:item_id => self.id)
  Post.delete_all(:item_id => self.id)
  View.delete_all(:item_id => self.id)
end

you could read more about delete_all here, keep in mind that delete_all and delete don't call any callbacks before_destroy or after_destroy, they also ignore any :dependent rules.

Upvotes: 3

Related Questions