Why does calling .delete_all on has_many relationship nullifies foreign keys.

24 views
Skip to first unread message

marcin.r...@gmail.com

unread,
Feb 18, 2014, 2:38:35 AM2/18/14
to rubyonra...@googlegroups.com
I have several years of Rails expirience and this little bit ALWAYS gets me:

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar  < ActiveRecord::Base
  belongs_to :foo
end

# after creating some foos and bars

foo.bars.delete_all #=>
UPDATE bars SET foo_id = NULL WHERE foo_id = $1

Yes I know I can set :dependant => :delete_all

but what's resoning behind this default behaviour? Is it just a legacy stuff?

I'd expect foo.bars.delete_all to act the same as Bar.delete_all or Bar.where(foo_id: foo.id).delete_all regardles of the :dependant option.

anyone knows why the default behaviour here is to nullify keys?

Adrien Siami

unread,
Feb 19, 2014, 3:36:32 AM2/19/14
to rubyonra...@googlegroups.com
You're calling delete_all on an association, even if it's weird, for rails, deleting an association means only breaking the links between the models, not effectively destroying the records. Semantically, this makes sense, but I grant you that it's a bit counter intuitive.

Robert Walker

unread,
Feb 19, 2014, 9:27:13 AM2/19/14
to rubyonra...@googlegroups.com
unknown wrote in post #1137005:
> Yes I know I can set :dependant => :delete_all
>
> but what's resoning behind this default behaviour? Is it just a legacy
> stuff?

> anyone knows why the default behaviour here is to nullify keys?

Actually, the Rails documentation explains this rather clearly, so the
behavior you're seeing is exactly as it was intended.

Excerpt:

delete_all()
Deletes all the records from the collection. For has_many associations,
the deletion is done according to the strategy specified by the
:dependent option. Returns an array with the deleted records.

If no :dependent option is given, then it will follow the default
strategy. The default strategy is :nullify. This sets the foreign keys
to NULL. For, has_many :through, the default strategy is delete_all.

--
Posted via http://www.ruby-forum.com/.

Wale Olaleye

unread,
Feb 19, 2014, 10:20:42 AM2/19/14
to rubyonra...@googlegroups.com
You should be using object.destroy and dependent: destroy in the model, instead of delete. Destroy is RESTful and will look to remove your dependent objects in the db, among other things.

-Wale
Reply all
Reply to author
Forward
0 new messages