Что делает Rails с обоими: зависимый =>: уничтожить и каскадно удалить / обнулить / ограничить
Я пытаюсь решить, как лучше установить (если вообще нужно) ограничения внешнего ключа для моего приложения rails. У меня есть модель Response
тот belongs_to
Prompt
, Я хотел бы использовать :dependent => :destroy
уничтожить призвал каждого Response
что принадлежит удаленному Prompt
и я пытаюсь решить, какое ограничение на удаление я должен наложить на мой внешний ключ.
Короче говоря, я хочу получить совет о том, как мне лучше всего воспользоваться преимуществами метода уничтожения зависимых объектов и ограничений внешнего ключа, чтобы гарантировать, что перебор не накапливается и отражает логическую структуру хранимых данных. Несколько более ранних вопросов, таких как " Должен ли я использовать ON DELETE CASCADE": зависимый =>: уничтожить или оба? и Rails: удалить каскад против зависимого уничтожения спросил, что было лучше, но на самом деле они мало говорят о том, как эти два варианта взаимодействуют и в каком порядке они запускаются или кажутся расплывчатыми.
На мой взгляд, соображения разбиваются на несколько частей:
- Есть ли
:dependent => :destroy
сначала вызовите destroy для зависимых объектов перед удалением родительского объекта из базы данных, поэтому уничтожение все равно будет вызываться для этих объектов, даже если я использую cascade delete? Есть ли
:dependent => :destroy
удалить зависимые объекты из базы данных до (или в транзакции с) удаления родителя из базы данных? Другими словами, если я установлю в cascade значение nullify, будет ли база данных расточительно аннулировать ссылки на дочерние объекты до того, как они будут удалены?Являются ли удаления, выпущенные в результате первоначального уничтожения, и связаны
:dependent => :destroy
опции, обернутые в транзакции, или, к сожалению, временные сбои оставят беспорядок в базе данных, если я не установлю каскадное удаление?- Наконец будет
:dependent => :destroy
убедиться, что родительский объект удален из базы данных, если я использую restrict в качестве параметра внешнего ключа on_delete?
0 ответов
С dependent: :destroy
В транзакции рельсы сначала уничтожают все зависимости, а только потом удаляют саму запись.
Может быть условие гонки: если зависимая запись была добавлена сразу после того, как рельсы прочитали коллекцию для уничтожения, но еще не удалили родителя - она может быть оставлена. Давайте назовем эти "записи о состоянии гонки" ниже.
да, вы можете использовать
dependent: :destroy
а такжеon delete cascade
таким образом, некоторые дочерние элементы (состояния гонки) могут быть удалены без обратных вызовов. Если обратные вызовы обязательны -on delete restrict
вместе с некоторыми блокировками и явным удалением потомков может быть лучше. Это как тоvalidates :some_field, uniqueness: true
это лучше подкрепить уникальным индексом, только согласованность данных может обеспечить сама база данных.так как родитель удаляется последним,
on delete nullify
не будет мешать (вы получите аннулированные записи о состоянии гонки)есть транзакция, заключающая в себе все удаления, могут быть оставлены только записи о состоянии гонки
on delete restrict
надdependent: :destroy
сработает только для записей условий гонки (и откатит всю транзакцию), но если условий гонки не было - рельсы удачно удалят все.