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

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?

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.

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.

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