Hi

Let's imagine these models, with ActiveRecord 4.0

class Parent < ActiveRecord::Base
  has_many :items
end

class Item < ActiveRecord::Base
  belongs_to :parent
end



I need to delete all items associated to one parent, without callback.
I don't need to call #destroy, but only executing the appropriate SQL 
statement.

First case :

> parent.items.delete_all


In Rails 4.1 delete_all on associations would not fire callbacks. It means 
if the :dependent option is :destroy then the associated records would be 
deleted without loading and invoking callbacks.

  Item Load (0.3ms)  SELECT "items".* FROM "items" WHERE 
"items"."parent_id" = ?  [["parent_id", 1]]

   (0.1ms)  begin transaction
  SQL (1.1ms)  DELETE FROM "items" WHERE "items"."id" = ?  [["id", 44]]
  SQL (0.1ms)  DELETE FROM "items" WHERE "items"."id" = ?  [["id", 43]]
  SQL (0.1ms)  DELETE FROM "items" WHERE "items"."id" = ?  [["id", 42]]
  SQL (0.1ms)  DELETE FROM "items" WHERE "items"."id" = ?  [["id", 41]]
  ...

   (80.0ms)  commit transaction



I got one delete per item. Not perfect !
Now, let's try a workaround :

> parent.items.scoped.delete_all

 

DEPRECATION WARNING: Model.scoped is deprecated. Please use Model.all 
instead.
  SQL (0.1ms)  DELETE FROM "items" WHERE "items"."parent_id" = ? 
 [["parent_id", 1]]


 
It works fine: only one statement.
But according to the warning, it seems to not be the proper way to do.

So, OK, let's try :

> feed.items.all.delete_all

 
 DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load 
a relation, you can call #load (e.g. `Post.where(published: true).load`).

If you want to get an array of records from a relation, you can call #to_a 
(e.g. `Post.where(published: true).to_a`).
  Item Load (0.3ms)  SELECT "items".* FROM "items" WHERE "items"."feed_id" 
= ?  [["feed_id", 1]]

 

NoMethodError: undefined method `delete_all' for #<Array:0x007f87ae6fee00>
from 
~/.rvm/gems/ruby-2.0.0-p0@global/gems/rush-0.6.8/lib/rush/find_by.rb:16:in 
`method_missing'
from (irb):24
from 
~/.rvm/gems/ruby-2.0.0-p0@global/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in
 
`start'
from 
~/.rvm/gems/ruby-2.0.0-p0@global/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in
 
`start'
from 
~/.rvm/gems/ruby-2.0.0-p0@global/gems/railties-4.0.0/lib/rails/commands.rb:64:in
 
`<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'


 
I also tried to call #load : I got the same result as for the first case 
(too many DELETE statements).
I can also do that :

> Item.where(feed: feed).delete_all

 

  SQL (0.2ms)  DELETE FROM "feed_items" WHERE "feed_items"."feed_id" = 1



Works fine. No warning. But let's forget the OOP.
So.. What's the proper way ?
 

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-talk+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-talk/2a3b9714-7dfc-415e-bc40-17e4573fddbe%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to