Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check all associations before destroy in rails

I have an important model in my application, with many associations. If I want to check all the references in a before_destroy callback, i'd have to do something like:

has_many :models_1
has_many :models_2
mas_many :models_3
....
....
has_many :models_n

before_destroy :ensure_not_referenced

def :ensure_not_referenced
   if models_1.empty? and models_2.empty? and models_3.empty? and ... and models_n.empty?
       return true
   else
       return false
       errors.add(:base,'Error message')
   end
end

The question is, is there a way to perform all the validations at once? Thanx!

like image 590
Dario Barrionuevo Avatar asked Jun 10 '11 01:06

Dario Barrionuevo


2 Answers

You can pass the :dependent => :restrict option to your has_many calls:

has_many :models, :dependent => :restrict

This way, you will only be able to destroy the object if no other associated objects reference it.

Other options are:

  • :destroy - destroys every associated object calling their destroy method.
  • :delete_all - deletes every associated object without calling their destroy method.
  • :nullify - sets the foreign keys of the associated objects to NULL without calling their save callbacks.
like image 55
Matheus Moreira Avatar answered Sep 19 '22 04:09

Matheus Moreira


Create a module into app/models/concerns/verification_associations.rb wiht:

module VerificationAssociations
  extend ActiveSupport::Concern

  included do
    before_destroy :check_associations
  end

  def check_associations
    errors.clear
    self.class.reflect_on_all_associations(:has_many).each do |association|
      if send(association.name).any?
        errors.add :base, :delete_association,
          model:            self.class.model_name.human.capitalize,
          association_name: self.class.human_attribute_name(association.name).downcase
      end
    end

    return false if errors.any?
  end

end

Create a new translation key into app/config/locales/rails.yml

en:
  errors:
    messages:
     delete_association: Delete the %{model} is not allowed because there is an
                         association with %{association_name}

In your models include the module:

class Model < ActiveRecord::Base
  include VerificationAssociations
end
like image 34
Diego Mtz Avatar answered Sep 21 '22 04:09

Diego Mtz