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 когда один из них переводится на что-то другое?

Другие вопросы по тегам