How to Use Uniqueness Validation in Ruby on Rails
validates :attribute, uniqueness: true inside your model to ensure a field's value is unique in the database. This validation checks before saving a record and prevents duplicates automatically.Syntax
The uniqueness validation is added inside a Rails model using validates. You specify the attribute to check and set uniqueness: true. Optionally, you can add scope to limit uniqueness within a group and case_sensitive to ignore case differences.
class User < ApplicationRecord validates :email, uniqueness: true # Optional: # validates :username, uniqueness: { scope: :account_id, case_sensitive: false } end
Example
This example shows a User model with uniqueness validation on the email attribute. It prevents saving two users with the same email.
class User < ApplicationRecord validates :email, uniqueness: true end # Usage in Rails console: user1 = User.create(email: 'test@example.com') user2 = User.new(email: 'test@example.com') user2.valid? # => false user2.errors.full_messages # => ["Email has already been taken"]
Common Pitfalls
Uniqueness validation only checks before saving and can miss duplicates if multiple requests happen simultaneously. Always add a unique index in the database for true uniqueness enforcement. Also, remember that uniqueness: true is case sensitive by default, so emails like Test@example.com and test@example.com are considered different unless you set case_sensitive: false.
class User < ApplicationRecord # Wrong: no database index, can cause duplicates in race conditions validates :email, uniqueness: true end # Correct: add unique index in migration class AddUniqueIndexToUsersEmail < ActiveRecord::Migration[7.0] def change add_index :users, :email, unique: true end end
Quick Reference
| Option | Description | Example |
|---|---|---|
| uniqueness: true | Enforces attribute uniqueness | validates :email, uniqueness: true |
| scope | Limits uniqueness to a group | validates :name, uniqueness: { scope: :account_id } |
| case_sensitive | Ignores case when false | validates :email, uniqueness: { case_sensitive: false } |
| message | Custom error message | validates :email, uniqueness: { message: 'already used' } |