What type of destroy action should you use in Ruby on Rails models?

When building models that depend on each other in a rails application, there will be a point where you are faced with a decision when deleting records. If you have a model, such as…

class Post < ActiveRecord::Base
  has_many :comments
end
class Comment < ActiveRecord::Base
  belongs_to :post
end

… and you try to delete a post that has child comment records, you will not be able to do this because it has dependent records. The default response is to include a foreign key constraint to avoid dependent records from being deleted unintentionally. You can give more specific guidance to your rails applications to tell it how to act in this scenario. You specify the action using the dependent keyword in your model, such as in the following example:

class Post < ActiveRecord::Base
   has_many :comments, dependent: :destroy
end

To destroy or to delete?

If you want to get rid of the dependent records, you have the following options:

  • :destroy sets all dependent models to call their own destroy action.
  • :delete_all deletes all dependent records from the database without calling their destroy action.
  • :nullify The child record is not destroyed, but its foreign key link to its parent is set to null.

One advantage of using destroy is that it triggers the callbacks for the destroy action on the record. For example, you could use the after_destroy callback to log a confirmation of the record being deleted.

Restrict

However, if you did not want to delete the record, the keyword :restrict will prevent dependent records from being deleted.

  • :restrict prevents the record being deleted but will not raise an exception or error.
  • :restrict_with_exception stops the dependent record from being deleted, while raising an exception.
  • :restrict_with_error raises an error when a parent record is attempted to be deleted.

Why might you want to use exceptions or errors? If you don’t then then the user may not know why a parent record cannot be deleted.

Read more