Just wasted a full day on this… Suppose you have a User model, with certain Users being children and other Users being parents. With the following code I intended to delete the parent when the child being deleted is the last child of the parent:
class ChildParent < ActiveRecord::Base belongs_to :child, :class_name => "User" belongs_to :parent, :class_name => "User" end class User < ActiveRecord::Base has_many :parents, :through => :child_parents_as_child has_many :child_parents_as_child, :foreign_key => :child_id, :class_name => "ChildParent", :dependent => :destroy has_many :children, :through => :child_parents_as_parent has_many :child_parents_as_parent, :foreign_key => :parent_id, :class_name => "ChildParent", :dependent => :destroy before_destroy :determine_parents_to_be_destroyed after_destroy :destroy_parents private def determine_parents_to_be_destroyed @destroy_parents =  self.parents.each do |p| @destroy_parents << p unless p.children.size > 1 end end def destroy_parents @destroy_parents.each do |p| p.destroy end end end
This didn’t work –
@destroy_parents was never populated. Finally I stumbled on the following sentence, clearly documented in the api for ActiveRecord, yet easily missed: *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won‘t be inherited.
after_destroy declarations above the associations solved the problem.