26

Can anyone tell me the difference between these two ways when dealing with object whose parent key is destroyed? What practical reason makes you choose one from the other?

Eric Chuhao Chan
  • 367
  • 1
  • 3
  • 5
  • [..how the situation is to be handled..](http://edgeguides.rubyonrails.org/association_basics.html) - one approach is very active, while the other is passive. – user2864740 Jan 03 '18 at 04:15
  • I like the "What practical reason makes you choose one from the other?" - wish the answers would address that. – karns Sep 23 '20 at 18:38

3 Answers3

30

restrict_with_exception

If there are any associated records, an exception will be raised with:

class Student< ActiveRecord::Base
  has_many :courses, dependent: :restrict_with_exception
  has_many :books
end

restrict_with_error

If there are any associated records, an error will be added to the owner (the record you are trying to delete) with:

class Foo < ActiveRecord::Base
  has_many :bars, dependent: :restrict_with_error
end

Expected behavior

For standard validations the error messages contain the translations and the error details contain the keys, as here with a blank error:

f1 = Foo.new
f1.save!
#=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
f1.errors
#=> #<ActiveModel::Errors:0x007fb666637af8
#=> @base=#<Foo:0x007fb6666ddbb0 id: nil, name: nil>,
#=> @details={:name=>[{:error=>:blank}], :type=>[{:error=>:blank}]},
#=> @messages={:name=>["can't be blank"], :type=>["can't be blank"]}>
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
9

Those are dependent option

What is the dependent option?

The dependent option is an option to decide what to do with child records when deleting a parent record if the model that is Rails has a child record.

restrict_with_exception

:restrict_with_exception – if there are any associated records, an exception will be raised.

:restrict_with_exception - if there are child records, then you ActiveRecord::DeleteRestrictionError will encounter.

restrict_with_error

:restrict_with_error – if there are any associated records, an error will be added to the owner (the record you are trying to delete).

:restrict_with_error - if there is a child record, it can not be deleted, and error information is added to the parent record.

Several Options except those

:destroy - Delete child records with parents.

:delete_all - Delete child records with parents. However, since the record of the DB is deleted directly, the callback processing of the child record is not executed.

:nullify NULL - Update the foreign key of the child record.

You can also google for more

fool-dev
  • 7,671
  • 9
  • 40
  • 54
1

From fool-dev's answer

You can also google for more

No need to do so. From the ActiveRecord source code:

def self.valid_dependent_options
  [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception, :destroy_async]
end

So, the list is almost complete, there would only be :destroy_async left to google. Here's what it does, from the docs:

If set to :destroy_async, the associated object is scheduled to be destroyed in a background job.

Andreas Gebhard
  • 361
  • 2
  • 8