ruby-on-rails - 如何在 Rails 验证中使用父记录的值

标签 ruby-on-rails validation parent-child

我有一个 Rails 3.2 应用程序,其中有一个简单的父/子关系,我需要使用父项中的值来验证子项中的属性。模型看起来像这样:

class RubricItem < ActiveRecord::Base
  attr_accessible :max_score, :min_score, :name, :order
  has_many :rubric_ranges
end

class RubricRange < ActiveRecord::Base
  attr_accessible :helper, :range_max, :range_min, :rubric_item_id
  validates_presence_of :helper, :range_max, :range_min
  validates :range_max, :range_min, :numericality => {:only_integer => true}
  validates :range_max, :numericality => { :greater_than => :range_min }
  belongs_to :rubric_item
end

我希望能够验证两个不同的事物。首先,对于 rubric_range,我想验证它的 range_min 值 >= 到它的父 rubic.min_score 并且 range_max <= 到它的父 rubric.max_score。

其次,我想验证其他 rubric_ranges 是否具有唯一的最小/最大值。换句话说,不能为同一个值定义两个 rubric_ranges,因此如果一个包含 0-2,则另一个不能在其范围内包含 0、1 或 2。示例:第一个范围是 0-2,如果定义了 2-4 范围,我想在父级范围内引发验证错误。

感谢您的帮助。

最佳答案

您几乎可以像使用 parent 一样使用 parent:

class RubricRange < ActiveRecord::Base
  ...
  validate :has_proper_range
  ...
  def has_proper_range
    error.add(:range_min, ' cannot be smaller than RubricItem minimum score') if range_min < rubric_item.min_score
    error.add(:range_max, ' cannot be greater than RubricItem maximum score') if range_max > rubric_item.max_score
  end

唯一的问题是,如果您想使用 nested_attributes 创建 RubricRange 项目和 RubricItem,因为关联的构建方法不会为新记录设置反向关系。

第二次验证可以通过简单地注意来完成,如果在给定范围内存在具有最小值或最大值的任何其他范围,则验证失败。因此:

validate :do_not_overlap_with_other_ranges
...
def do_not_overlap_with_other_ranges
  overlapping_ranges = self.class.where('(range_min >= :min AND range_min <= :max) OR (range_max >= :min AND range_max <= :max)', {:min => range_min, :max => range_max})
  overlapping_ranges = overlapping_ranges.where.not(:id => id) unless new_record?
  errors.add(:base, 'Range overlapping with another range') if overlapping_ranges.exists?
end

(请随时对上面的查询发表评论,因为我认为应该有更好的写法)。

关于ruby-on-rails - 如何在 Rails 验证中使用父记录的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18698428/

相关文章:

ruby-on-rails - mysql2 gem 出现 Gem::LoadError,但它已经在 Gemfile 中

css - 无法覆盖导航栏中的 bootstrap .active 类

c# - 针对包含逗号分隔电子邮件的字符串进行验证

python - 使用 Flask 从 WTForm 进行电子邮件验证

PHP:从子类访问 protected var

c++ - 如何在 C++ 中创建包含子类的类的链表?

Angular 2 + Material 2 工具栏嵌套 Sidenav - 如何在 Sidenav 外部调用切换按钮

mysql - 使用 Rails 应用程序中存在于多个数据库中的表

ruby-on-rails - 如何在 Rails 3 中呈现 View 后调用方法

javascript - 在没有 DOM 操作或 jQuery 的情况下,如何在 AngularJS 中制定指令来验证电子邮件或密码确认?