Friday, October 21, 2022

[FIXED] Why does ActiveRecord has_many use delete_all instead of destroy_all?

Issue

I have a model which has many children. I was setting/removing the children as such:

mymodel.children_ids = [1,2,3]
mymodel.save #add the children
mymodel.children_ids = [1]
mymodel.save #remove children 2,3

This works just fine, but I just realized that none of the callbacks (i.e. after_destroy) are not being called on the children model.

After some digging, it turns out that the delete_all function is being executed, rather than destroy_all. As the docs correctly state, the delete_all function does not fire off the callbacks, so is there anyway to change this behavior?

Thanks.


Solution

For those interested, I added the following monkeypatch to force the has_many through to perform a destroy_all, rather than delete_all. There might be a better way, so I'm open to suggestions.

module ActiveRecord 
  module Associations
    class HasManyThroughAssociation < HasManyAssociation       
      def delete_records(records)
        klass = @reflection.through_reflection.klass
        records.each do |associate|
          klass.destroy_all(construct_join_attributes(associate)) #force auditing by using destroy_all rather than delete all
        end
      end
    end
  end
end


Answered By - gmoniey
Answer Checked By - David Goodson (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.