0
0
RailsHow-ToBeginner · 3 min read

How to Use Uniqueness Validation in Ruby on Rails

In Ruby on Rails, use 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.

ruby
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.

ruby
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"]
Output
false ["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.

ruby
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

OptionDescriptionExample
uniqueness: trueEnforces attribute uniquenessvalidates :email, uniqueness: true
scopeLimits uniqueness to a groupvalidates :name, uniqueness: { scope: :account_id }
case_sensitiveIgnores case when falsevalidates :email, uniqueness: { case_sensitive: false }
messageCustom error messagevalidates :email, uniqueness: { message: 'already used' }

Key Takeaways

Use validates :attribute, uniqueness: true inside your model to check uniqueness.
Add a unique index in the database to prevent race condition duplicates.
Set case_sensitive: false to ignore letter case in uniqueness checks.
Uniqueness validation runs before saving and adds error messages if duplicates exist.
Use scope option to enforce uniqueness within a subset of records.