9

我有一个使用条件定义的唯一约束。但以下测试未通过:

class Dummy
  include Mongoid::Document

  field :name, :type => String
  field :status, :type => Boolean

  validates_uniqueness_of :name, if: :status
end


describe "UniquenessValidator" do
  let!(:d1) { Dummy.create!(name: 'NAME_1', status: true) }
  let!(:d2) { Dummy.create!(name: 'NAME_1', status: false) }

  it "should raise an error" do
    expect {
      d2.status = true
      d2.save!
    }.to raise_error
  end
end

由于name_changed?为假,似乎没有发生验证,因此不检查唯一性条件。

这是一个错误吗?还是我忘记了什么?我想这是一种优化,可以避免每次修改元素时都运行验证。

在那种情况下,当状态改变时触发验证的好方法是什么?

谢谢!

4

2 回答 2

6

由于您的情况是边缘情况,我建议您为此创建自己的验证器类,这样的事情应该可以工作:

class NameUniquenessValidator < Mongoid::Validatable::UniquenessValidator
private
  def validation_required?(document, attribute)
    return true "name" == attribute.to_s
    super
  end
end

class Dummy
  include Mongoid::Document

  field :name, :type => String
  field :status, :type => Boolean

  validates_with(NameUniquenessValidator, :name, if: :status)
end
于 2013-10-29T16:16:02.170 回答
1

您正在更新状态字段,因此您需要验证此字段。你可以这样做:

class Dummy
  include Mongoid::Document

  field :name, :type => String
  field :status, :type => Boolean

  validates_uniqueness_of :name, if: :status
  validates_uniqueness_of :status, scope: :name, if: :status
end

我不知道您是否可以在更新单个字段时强制 mongoid 验证所有字段。

于 2013-10-29T09:20:58.410 回答