Rails полиморфно-зависимый:destroy не работает корректно
Допустим, у меня есть три модели Active Record:
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
Допустим, мое приложение может перенести бугер с пальца на ткань, и как только это будет сделано, палец будет уничтожен (yikes!). По какой-то причине, когда палец разрушается, он также разрушает бугеры, которые ранее принадлежали ему и с тех пор были перенесены в ткань. В журнале я вижу, что когда палец уничтожен, он запоминает идентификатор использованных для этого бугеров и уничтожает их. Он не проверяет, является ли boogerable_type по-прежнему 'finger' и таким образом уничтожает те, которые имеют тип 'fabric'.
Когда палец разрушен, он делает это:
DELETE FROM boogers WHERE booger.id = 387
Когда это должно быть сделано:
DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger'
Кто-нибудь сталкивался с этим раньше?
1 ответ
Во-первых, вы должны знать, что ActiveRecord destroy
метод использует объект :id
поле, когда оно должно уничтожить его. И что dependent: :destroy
опция активирует destroy
метод на все объекты, которые связаны с текущим объектом.
Я предполагаю, что вы делаете что-то вроде этого:
f = Finger.find(finger_id)
t = Tissue.find(tissue_id)
f.boogers[0].boogerable = t
f.boogers[0].save!
f.destroy
dependent: :destroy
утверждение означает, что когда destroy
призван f
, он также будет вызываться на всех усилителях, связанных с f
, И с тех пор f
и его бугеры загружаются в память, f.booger[0]
объект все еще существует в массиве f.boogers
который будет иметь каждый из своих элементов, в том числе boogers[0]
уничтожен, когда f
уничтожен
Решение этого дела заключается в том, что вы нажмете f.boogers.reload
обновить массив перед вызовом f.destroy
,
Также обратите внимание, что при уничтожении f
, все связанные boogers
будет destroy
также, это действительно то, что вы хотите? уничтожить палец со всеми остальными связанными boogers
когда один из них переводится на что-то другое?