Associations are not consistent in honoring :dependent => destroy (db is fill with orphaned objects)

if a model A has_many :bee, :through => :c, :dependent => :destroy ... a.destroy properly cleans up all the bee's ...

however. If one does this:

a.bees = c records are destroyed... bees are untouched.

This is misleading to me, as: while I can understand semantics that just the "array" has been modified... something like :dependent => :destroy should be invariant (the dependents should be destroyed, under all cases where... the object is a dependent)

I am new to this list, so: how does one file a ticket?

-Solas

The behaviour of deletion/destruction on associations can be confusing, and there is a lack of documentation. I have done some work recently to improve consistency across the different types of associations, and improve the documentation too.

So the current situation in master is that:

* delete/destroy on an association removes the "link", and not necessarily the actual associated records. For has_many the "link" is the records itself, so there is no distinction. For has_many :through and has_and_belongs_to_many, only the join/through record is removed as this is the "link".

* Doing a.association.delete(*records) will perform the deletion according to the :dependent option. Using the :dependent option basically causes a before_destroy callback to call a.association.delete_all.

With has_many :through, if you want to remove the associated records also, then you should probably add the :dependent option to the source association in your join model.

Jon

rails.lighthouseapp.com is where to file a ticket.

However, I don't think this is a bug - :dependent => :destroy only specifies what happens when the object that declares the association gets destroyed - in your second case, you're not destroying 'a'.

If you *really* want this behavior, you can probably get it with :dependent => :destroy on the association in model 'C', but the resulting behavior will make *lots* of records vanish that you might not have intended. For instance, here's a simple set of associations:

class Project < AR::Base   has_many :task_assignments, :dependent => :destroy # 1   has_many :users, :through => :task_assignments end

class TaskAssignment < AR::Base   belongs_to :project, :dependent => :destroy #3   belongs_to :user end

class User < AR::Base   has_many :task_assignments, :dependent => :destroy # 2   has_many :projects, :through => :task_assignments end

the lines labelled #1 and #2 above are typically a good idea, as they ensure that join records referencing an object are cleaned up when the object is destroyed. #3, on the other hand, means that deleting a user will delete every Project that user was assigned to, as will doing 'user.projects = '...

--Matt Jones

Please note that the documentation clearly says the :dependent option is ignored altogether for hmt. It is better to work on the join model.

Hey,