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!
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With