DRYup在before_destroy上共享模型验证

时间:2013-04-20 04:07:19

标签: ruby-on-rails-3 validation callback dry

为了防止删除相关记录,我在每个模型上应用了before_destroy回调方法

我在模块中定义了几个相关记录验证方法,以便可以将它们共享给不同模型的before_destroy回调:

class Teacher < ActiveRecord::Base
  include RelatedModels
  before_destroy :has_courses
  ...
end

class Level < ActiveRecord::Base
  include RelatedModels
  before_destroy :has_courses
  ...
end

module RelatedModels

  def has_courses
    if self.courses.any?
      self.errors[:base] << "You cannot delete this while associated courses exists"
      return false
    end
  end

  def has_reports
    if self.reports.any?
      self.errors[:base] << "You cannot delete this while associated reports exists"
      return false
    end
  end

  def has_students
    if self.students.any?
      self.errors[:base] << "You cannot delete this while associated students exists"
      return false
    end
  end

  ...

end

但它看起来不是很干

知道怎么用单一方法做到吗? 元编程不是我的技能

提前致谢

1 个答案:

答案 0 :(得分:0)

您可能想尝试observer class

这些在Rails 4中被折旧(您必须使用rails-observers gem),但似乎仍然是Rails 3核心的一部分


观察员类

“监听”模型中的指定操作,并提供扩展功能。正如他们的文档所述,它们特别适合于消除模型的混乱,允许您将许多功能组合到一组中央功能中

以下是您可能想要做的事情(请记住我只在Rails 4中使用过这些内容):

class RelatedObserver < ActiveRecord::Observer
  observe :teachers, :school

  def before_destroy(record)
      associations = %w(teachers schools reports)
      associations.each do |association|
          if record.send(association).any?
              self.errors[:base] << "You cannot delete this while associated #{association.pluralize} exists"
              return false
          end
      end
  end
end

这是good resource给你的