What Rails does with both: depend =>: destroy and cascade delete / nullify / restrict

I am trying to decide how best to configure (if at all) the external key constraints for my rails application. I have a Response model that belongs_to a Prompt . I would like to use :dependent => :destroy to call destroy on each Response that belongs to the remote Prompt , and I am trying to decide which delete restriction I should place on my foreign key.

In short, I need advice on how I can best use both the destroy method for dependent objects and foreign key constraints to ensure that the cool does not accumulate and does not reflect the logical structure of the stored data. A few previous questions, such as Should I use ON DELETE CASCADE ,: dependent =>: destroy or both? and Rails: removing the cascade against dependent destruction asked what was better, but they don’t talk very much about how the two options interact and in what order they work or seem vague in this matter.

As I see it, the considerations seem to break into several parts:

  • Does the call :dependent => :destroy first on dependent objects before removing the parent from the database, so destruction will be called on these objects, even if I use cascading deletion?
  • Does :dependent => :destroy remove :dependent => :destroy dependent objects from the database before (or in the transaction) with the parent removed from the database? In other words, if I set up a cascade for invalidation, does the database end up emptying references to child objects before they are deleted?

  • Are the original options for destruction and binding deleted :dependent => :destroy , wrapped in a transaction, or, unfortunately, during short-term database failures, if I do not install cascading deletion?

    / li>
  • Finally, will :dependent => :destroy ensure that the parent will be deleted from the database if I use the constraint as a foreign key parameter on_delete?
+10
ruby-on-rails foreign-keys cascade
source share
1 answer

With dependent: :destroy in a transaction, rails first destroys all the dependencies, and only then deletes the record itself.

There may be a condition for the race: if the dependent record was added immediately after the rails read the collection for destruction, but have not yet deleted the parent, it can be left. Let me call these race records below.

  1. yes, you can use dependent: :destroy and on delete cascade , so some children (race conditions) can be deleted without callbacks. If callbacks are required - on delete restrict along with some locks and explicit child deletion may be better. This is similar to validates :some_field, uniqueness: true which is best maintained by a unique index, only the database can ensure data consistency.

  2. since the parent is the last to be deleted, on delete nullify will not interfere (you will receive canceled race status records)

  3. there a transaction that wraps all deleted ones can be left only race status records

  4. on delete restrict by dependent: :destroy will only work for recording race conditions (and roll back the entire transaction), but if there were no race conditions, the rails will successfully delete everything.

0
source share

All Articles