2

我正在做一个 RoR 项目,我想对我的一个模型进行唯一性验证,以检查自定义范围:

class Keyword < ActiveRecord::Base
  belongs_to :keyword_list

  scope :active, -> { where("expiration > ?", DateTime.now) }

  validates :name, uniqueness: { scope: [:active, :keyword_list_id] }
end

只是,这行不通。它检查数据库中不存在的活动列并引发此错误:

ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column keywords.active does not exist

那么,我的问题是有什么办法可以使这项工作,还是我必须编写一个自定义验证器?如果是这样,是否有关于过度访问数据库应该是什么样子的任何提示?

4

1 回答 1

2

不,您必须编写自定义验证。

尝试这个。

# In app/models/keyword.rb

validate :freshness

private

def freshness
  if Keyword.active.find_by(name: self.name, keyword_list_id: self.keyword_list_id)
    errors.add(:base, "Name is not fresh enough.") # Fails the validation with error message
  end
end

这是另一个有趣的点,您不能依赖validates_uniqueness_of, 或 rails 中的任何其他唯一性验证器,因为验证不是自动运行的,这意味着如果同时插入两条相同的记录,并且没有SQL 约束验证唯一性,则 ruby​​ 验证将通过,两条记录都将被插入。

我在这里想说的是,如果您的验证是关键任务,请使用 SQL 约束。

于 2014-01-24T17:29:05.983 回答