Let's say I have three Active Record models:
class Tissue
has_many :boogers, as: :boogerable, dependent: :destroy
end
class Finger
has_many :boogers, as: :boogerable, dependent: :destroy
end
Class Boogers
belongs_to :boogerable, polymorphic: true
end
Let's say my application can transfer a booger from a finger to a tissue, and once that's done, the finger is destroyed (yikes!). For some reason, when the finger is destroyed, it is also destroying the boogers that previously belonged to it and were since transferred to a tissue. In the log I can see that when the finger is destroyed it remembers the ID of boogers that USED to belong to it and destroys them. It doesn't check to make sure the boogerable_type is still 'finger' and thus destroys the ones with type 'tissue'.
When a finger is destroyed, it is doing this:
DELETE FROM boogers WHERE booger.id = 387
When it should be doing this:
DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger'
Anyone come across this before?
First, you need to know that the ActiveRecord destroy
method uses the object's :id
field when it needs to destroy it. And that the dependent: :destroy
option will trigger the destroy
method upon all objects that are assciated with the current object.
I assume that you're doing something like this:
f = Finger.find(finger_id)
t = Tissue.find(tissue_id)
f.boogers[0].boogerable = t
f.boogers[0].save!
f.destroy
The dependent: :destroy
statement means that when destroy
is called upon f
, it will also be called upon all boogers that are associated with f
. And since f
and its boogers are loaded into memory, the f.booger[0]
object still exists in the array of f.boogers
which will have each of its elements, including boogers[0]
, destroyed when f
is destroyed.
The solution of this case is that you hit f.boogers.reload
to update the array before calling f.destroy
.
Also, please note that when you destroy f
, all associated boogers
will be destroy
ed as well, is that really what you want? destroy the finger with all remaining associated boogers
when one of them is transferred to something else?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With