Skip to content

Steve Hill

003: Rails Sexy Validations Gotcha -- Validating Uniqueness

rails1 min read

Note It's not very safe to only have the unique constraint in your code. It should be in your database to avoid a situation where two instances of the application write to the database with the same value at the same time.


Rails 3 brought about sexy validations. These are ways to more intuitively define what is and is not valid for the attributes of your models. When trying to validate unique records, I was surprised to find that it was case sensitive ('Case' and 'case' are considered unique).


The new syntax supports lots of interesting things like

1validates :name, :presence => true, :uniqueness => true

While using the fantastic shoulda gem from thoughtbot, I quickly found out that one cannot currently validate case-insensitivity the new way without writing a custom validation.


For the attributes I need to be unique regardless of case, I've stuck with the older syntax.

1validates_uniqueness_of :name, :case_sensitive => false

The new, lighter syntax is more fun and readable to use when it works for your needs. All functionality doesn't yet appear to be there.


Rails 3 API Docs

Shoulda Test

1require 'test_helper'
1class UserTest < ActiveSupport::TestCase
2 context "user creation" do
3 subject { Factory(:charles) }
4 should validate_presence_of :name
5 should validate_uniqueness_of(:name).case_insensitive
6 end

Shoulda Result Without case_sensitive => false

Expected errors to include "has already been taken" when name is set to "cHARLES", got no errors.Expected block to return true value.