diff --git a/.gitignore b/.gitignore index dc38eb5524..5f36918013 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ doc/* *.profile *.profile.pdf *.symbols +.idea \ No newline at end of file diff --git a/lib/mongoid/validatable/uniqueness.rb b/lib/mongoid/validatable/uniqueness.rb index 468b5c62a6..4dfb3fd145 100644 --- a/lib/mongoid/validatable/uniqueness.rb +++ b/lib/mongoid/validatable/uniqueness.rb @@ -124,6 +124,8 @@ def create_criteria(base, document, attribute, value) # # @since 2.3.0 def criterion(document, attribute, value) + attribute = document.class.aliased_fields[attribute.to_s] || attribute + if localized?(document, attribute) conditions = value.inject([]) { |acc, (k,v)| acc << { "#{attribute}.#{k}" => filter(v) } } selector = { "$or" => conditions } diff --git a/spec/app/models/definition.rb b/spec/app/models/definition.rb index c28ea93775..6ffc1ebf9f 100644 --- a/spec/app/models/definition.rb +++ b/spec/app/models/definition.rb @@ -1,7 +1,7 @@ class Definition include Mongoid::Document field :description, type: String - field :part, type: String + field :p, as: :part, type: String field :regular, type: Boolean embedded_in :word end diff --git a/spec/mongoid/validatable/uniqueness_spec.rb b/spec/mongoid/validatable/uniqueness_spec.rb index e86af02e81..e69726d813 100644 --- a/spec/mongoid/validatable/uniqueness_spec.rb +++ b/spec/mongoid/validatable/uniqueness_spec.rb @@ -89,6 +89,55 @@ end end + context "when the field name is aliased" do + + before do + Dictionary.create!(language: "en") + end + + let(:dictionary) do + Dictionary.new(language: "en") + end + + after do + Dictionary.reset_callbacks(:validate) + end + + context "when the validation uses the aliased name" do + + before do + Dictionary.validates_uniqueness_of :language + end + + it "correctly detects a uniqueness conflict" do + expect(dictionary).to_not be_valid + end + + it "adds the uniqueness error to the aliased field name" do + dictionary.valid? + expect(dictionary.errors).to have_key(:language) + expect(dictionary.errors[:language]).to eq([ "is already taken" ]) + end + end + + context "when the validation uses the underlying field name" do + + before do + Dictionary.validates_uniqueness_of :l + end + + it "correctly detects a uniqueness conflict" do + expect(dictionary).to_not be_valid + end + + it "adds the uniqueness error to the underlying field name" do + dictionary.valid? + expect(dictionary.errors).to have_key(:l) + expect(dictionary.errors[:l]).to eq([ "is already taken" ]) + end + end + end + context "when the field is localized" do context "when no scope is provided" do @@ -2012,6 +2061,55 @@ end end end + + context "when the field name is aliased" do + + before do + word.definitions.build(part: "noun") + end + + let(:definition) do + word.definitions.build(part: "noun") + end + + after do + Definition.reset_callbacks(:validate) + end + + context "when the validation uses the aliased name" do + + before do + Definition.validates_uniqueness_of :part, case_sensitive: false + end + + it "correctly detects a uniqueness conflict" do + expect(definition).to_not be_valid + end + + it "adds the uniqueness error to the aliased field name" do + definition.valid? + expect(definition.errors).to have_key(:part) + expect(definition.errors[:part]).to eq([ "is already taken" ]) + end + end + + context "when the validation uses the underlying field name" do + + before do + Definition.validates_uniqueness_of :p, case_sensitive: false + end + + it "correctly detects a uniqueness conflict" do + expect(definition).to_not be_valid + end + + it "adds the uniqueness error to the underlying field name" do + definition.valid? + expect(definition.errors).to have_key(:p) + expect(definition.errors[:p]).to eq([ "is already taken" ]) + end + end + end end context "when the document uses composite keys" do