Проверьте все ассоциации, прежде чем уничтожить в рельсах - PullRequest
8 голосов
/ 10 июня 2011

У меня есть важная модель в моем приложении, со многими ассоциациями. Если я хочу проверить все ссылки в обратном вызове before_destroy, мне нужно сделать что-то вроде:

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

Вопрос в том, есть ли способ выполнить все проверки сразу? Thanx!

Ответы [ 2 ]

23 голосов
/ 10 июня 2011

Вы можете передать опцию :dependent => :restrict на ваши has_many звонки:

has_many :models, :dependent => :restrict

Таким образом, вы сможете уничтожить объект, только если другие связанные объекты не ссылаются на него.

Другие опции:

  • :destroy - уничтожает каждый связанный объект, вызывая их метод destroy.
  • :delete_all - удаляет каждый связанный объект без , вызывая их destroy метод.
  • :nullify - устанавливает внешние ключи связанных объектов на NULL без , вызывая их обратные вызовы сохранения.
1 голос
/ 26 июня 2014

Создайте модуль в app / models / беспокойства / verify_associations.rb с:

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

Создать новый ключ перевода в app / config / locales / rails.yml

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

В ваших моделях есть модуль:

class Model < ActiveRecord::Base
  include VerificationAssociations
end
...