Search code examples
ruby-on-railsrubyruby-on-rails-7validates-uniqueness-of

Activerecord validates uniqueness does not work with scope and case_sensitive


I'm using Rails 7 and I try to validate the uniqueness of multiple columns using scope regardless of the case, as follow:

validates :attr1, uniqueness: { scope: %i[attr2 attr3], case_sensitive: false }

The following spec passes

it "is not valid without a unique attr1, attr2, and attr3" do
  model = create(:model)
  expect(build(:model, attr1: model.attr1, attr2: model.attr2, attr3: model.attr3)).to_not be_valid
end

But this fails

it "is not valid without a unique attr1, attr2, and attr3 (case sensitive)" do
  model = create(:model)
  expect(build(:model, attr1: model.attr1.upcase, attr2: model.attr2.upcase, attr3: model.attr3.upcase)).to_not be_valid
end

What am I doing wrong?


Solution

  • Suppose you try to save two instances of the model with attributes:

    first instance: first_name: Frank, last_name: Smith, fav_color: Blue

    second instance: first_name: FRANK, second_name: SMITH, fav_color: BLUE

    and your uniqueness validation on fav_color is:

    validates :fav_color, uniqueness: { scope: %i[first_name last_name], case_sensitive: false }
    

    The second instance is valid under the case-insensitive uniqueness constraint because the scope is different ("FRANK SMITH" vs. "Frank Smith"). The case insensitivity pertains to the attribute being validated... not the scope.