Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoid : The Validation "validates_uniqueness_of" is only triggered when the specific field changes

Tags:

ruby

mongoid

I have a unique constraint defined using a condition. But the following test does not pass :

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

Since name_changed? is false, no validation seems to happen and therefore the uniqueness condition is not checked.

Is it a bug ? Or have I forgotten something ? I guess it's an optimization to avoid to run the validation each time the element is modified.

In that case what is the good way to trigger the validation when the status is changed ?

Thanks!

like image 602
Aymeric Avatar asked Oct 23 '13 16:10

Aymeric


2 Answers

As you case is a edge case, I would advice you to create your own validator class for this, something like this should work:

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
like image 196
Arthur Neves Avatar answered Oct 16 '22 05:10

Arthur Neves


You are updating the status field so, you need to validate this field. You can do something like this:

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

I don't know if you can force mongoid to validate all fields when you update a single field.

like image 33
drinor Avatar answered Oct 16 '22 03:10

drinor