检查是否包含在ActiveRecord has_many关联中

时间:2009-10-27 23:57:30

标签: ruby-on-rails

我遇到以下问题:

我有一个名为Widget的ActiveRecord模型,它有一些字段,我们称之为field_a和field_b,以及标准的Rails字段。我还有一个名为Person的模型,它通过has_many关联(Person.widgets)有许多小部件。

在我的Widget控制器的创建动作中,我想检查以确保我从params {@widget = Widget.new(params [:widget])}创建的新Widget在Person中不存在.widgets集合在将新窗口小部件保存到数据库之前但是使用Person.widgets.include?(@ widget)并没有给我想要的结果,如果field_a和field_b与集合中的窗口小部件具有相同的值。

我猜这是因为新的小部件(@widget)在技术上并不存在于该集合中,因为它是一个新的记录,即使它的重要属性(field_a和field_b)可能与已经在与之关联的数据库中的属性相匹配人的实例。

关于如何检查这一点的任何想法,所以我不在与同一个Person实例关联的数据库中创建功能上重复的小部件?我试图覆盖哈希,eql?在Widget模型上的===方法,但这打破了其他一些东西......谢天谢地! : - )

谢谢, 麦克

2 个答案:

答案 0 :(得分:0)

是否有理由不能只使用ActiveRecord::Validations#validates_uniqueness_of

validates_uniqueness_of :field_a, :scope => [:person_id, :field_b]
validates_uniqueness_of :field_b, :scope => [:person_id, :field_a]

即使验证消息有时可能有点令人困惑,也应该这样做。但这就是:验证的消息选项适用于。

答案 1 :(得分:0)

class Widget
  before_save :validate_unique_for_person
  def matches?(w)
    field_a == w.field_a && field_b == w.field_b
  end
  def validate_unique_for_person
    errors.add("base","widget already exists for person") if person.widgets.any? { |w| matches?(w) && self != w }
  end
end