Hacker News new | past | comments | ask | show | jobs | submit login

I'm interested in point 4: use SQL. Is there a way of doing a find that only returns the primary key value and then do a delete only based on this value without using SQL and only via Active Record?



ActiveRecord::Base#delete_all allows you to delete directly in the database. For example:

  Person.delete_all("created_at < '2012-01-01'") 
will generate the sql command

  "delete from persons where created_at < '2012-01-01'"
You can use normal AR conditions of course. For example:

  Person.delete_all(["created_at < ?", Time.now.beginning_of_year]) 
That will not run any callbacks of course since the data is never being pulled back into your code and AR objects are not instantiated. If you need callbacks to run (for example to delete or update related objects) then look at the much slower ActiveRecord::Base#destroy_all.


You should be using the new ARel scoping mechanisms introduced in 3.x. See xentronium's comment (http://news.ycombinator.com/item?id=3935050).


Do you mean something like this?

    ids = Post.where(:published => true).pluck(:id) 
    Post.where(:id => ids).delete_all
or this

    Post.where(:published => true).delete_all

?


The second variant seems much better to me - in the first variant the size of the DELETE query itself is proportional to the number of published posts, so for very large numbers of published posts you'll end up sending a lot of data over the network, and may even hit your max_allowed_packet size (though it defaults to 1GB, which would be a lot of published posts!).


You might want to use 'destroy' instead of 'delete', as 'delete' skips all ActiveRecord callbacks (i. e., if you had a dependent: :destroy callback for post comments, using 'delete' would leave them intact)


`destroy` instantiates active record models which kind of defeats the purpose of fast deletion :)


You are right, well in that case, you would have to delete associated records manually if you didn't add any foreign keys at the db level


I'd suggest deleting or dealing with those records anyway, regardless of whether you added FKs! But... if you don't add FKs, you've got bigger issues to deal with :(


this is why i prefer using "on delete cascade" in schemas, no need to transmit lots of data over the wire and instantiate thousands of slow activerecord objects when deleting stuff.


Though you're still left to deal with your destroy callbacks/observers, if you have any.


I looked up the API documentation for pluck... That definitely looks like what I'm talking about :-)

Does the second query translate to a straight DELETE?


Yes - `delete from posts where published = 1;` (or however your particular database adapter translates true)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: