collectiveidea / audited

Audited (formerly acts_as_audited) is an ORM extension that logs all changes to your Rails models.
MIT License
3.39k stars 686 forks source link

Best way to audit has_many through collection records deleted from assignment? #372

Open jasonperrone opened 7 years ago

jasonperrone commented 7 years ago

If you have a has_many :through collection, and records in that collection are going to be deleted because you set that collection = to a new set of ids, which did not include some existing ids in that collection, then of course those records are removed from the database. Problem is starting in Rails 4 those are removed with deletes instead of destroys and so the before_destroy callback is not called. I changed many HABTMs to has_many throughs just so I could audit the lifecycle of these join table records and it worked great in Rails 3.2. But now, those callbacks don't even get called anymore.

So, what is the answer? Do I add a before_remove :audit_destroy on the has_many through? Do I change my code so that before setting the collection = to a new set of IDs I explicitly go through and destroy the ids that I know will be getting deleted? Seems Audited would have thought of this and added, say, before_remove callbacks in addition to before_destroy, or something at all to handle this situation. Am I really the first person to run into this because I'm not really seeing anything in the issues list.

jasonperrone commented 7 years ago

For now, I have gone the route of manually destroying the ids. So for instance instead of being able to do this: user.role_ids = params[:role_ids]

I need two lines of code user.roles.select{|r| deleted_roles.include?(r)}.map(&:destroy) user.role_ids = params[:role_ids]

and of course that doesn't include the code I needed to figure out deleted_roles. Not good.

diecrf commented 7 years ago

I had the same problem and I have solved it adding dependent: destroy in the has_many :through relationships, as explained in #246