Что делает Rails с обоими: зависимый =>: уничтожить и каскадно удалить / обнулить / ограничить

Я пытаюсь решить, как лучше установить (если вообще нужно) ограничения внешнего ключа для моего приложения rails. У меня есть модель Response тот belongs_to Prompt, Я хотел бы использовать :dependent => :destroy уничтожить призвал каждого Response что принадлежит удаленному Prompt и я пытаюсь решить, какое ограничение на удаление я должен наложить на мой внешний ключ.

Короче говоря, я хочу получить совет о том, как мне лучше всего воспользоваться преимуществами метода уничтожения зависимых объектов и ограничений внешнего ключа, чтобы гарантировать, что перебор не накапливается и отражает логическую структуру хранимых данных. Несколько более ранних вопросов, таких как " Должен ли я использовать ON DELETE CASCADE": зависимый =>: уничтожить или оба? и Rails: удалить каскад против зависимого уничтожения спросил, что было лучше, но на самом деле они мало говорят о том, как эти два варианта взаимодействуют и в каком порядке они запускаются или кажутся расплывчатыми.

На мой взгляд, соображения разбиваются на несколько частей:

  1. Есть ли :dependent => :destroy сначала вызовите destroy для зависимых объектов перед удалением родительского объекта из базы данных, поэтому уничтожение все равно будет вызываться для этих объектов, даже если я использую cascade delete?
  2. Есть ли :dependent => :destroy удалить зависимые объекты из базы данных до (или в транзакции с) удаления родителя из базы данных? Другими словами, если я установлю в cascade значение nullify, будет ли база данных расточительно аннулировать ссылки на дочерние объекты до того, как они будут удалены?

  3. Являются ли удаления, выпущенные в результате первоначального уничтожения, и связаны :dependent => :destroy опции, обернутые в транзакции, или, к сожалению, временные сбои оставят беспорядок в базе данных, если я не установлю каскадное удаление?

  4. Наконец будет :dependent => :destroy убедиться, что родительский объект удален из базы данных, если я использую restrict в качестве параметра внешнего ключа on_delete?

0 ответов

С dependent: :destroy В транзакции рельсы сначала уничтожают все зависимости, а только потом удаляют саму запись.

Может быть условие гонки: если зависимая запись была добавлена ​​сразу после того, как рельсы прочитали коллекцию для уничтожения, но еще не удалили родителя - она ​​может быть оставлена. Давайте назовем эти "записи о состоянии гонки" ниже.

  1. да, вы можете использовать dependent: :destroy а также on delete cascadeтаким образом, некоторые дочерние элементы (состояния гонки) могут быть удалены без обратных вызовов. Если обратные вызовы обязательны - on delete restrict вместе с некоторыми блокировками и явным удалением потомков может быть лучше. Это как то validates :some_field, uniqueness: true это лучше подкрепить уникальным индексом, только согласованность данных может обеспечить сама база данных.

  2. так как родитель удаляется последним, on delete nullify не будет мешать (вы получите аннулированные записи о состоянии гонки)

  3. есть транзакция, заключающая в себе все удаления, могут быть оставлены только записи о состоянии гонки

  4. on delete restrict над dependent: :destroy сработает только для записей условий гонки (и откатит всю транзакцию), но если условий гонки не было - рельсы удачно удалят все.

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