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
erro开发者_如何学Pythonrs.add(:base,'Error message')
end
end
The question is, is there a way to perform all the validations at once? Thanx!
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 theirdestroy
method.:delete_all
- deletes every associated object without calling theirdestroy
method.:nullify
- sets the foreign keys of the associated objects toNULL
without calling their save callbacks.
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
精彩评论