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

は false であるため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 に答える