Mark Thomas Miller's logo

How to validate the uniqueness of two columns in Ruby on Rails

January 24, 2019

Here's a quick write-up on how to validate the uniqueness of two columns in Rails – in other words, how to prevent a combination of two columns from being identical in a certain table.

Let's say you have an application with lots of Users who belongs to Groups. Each user can have a different Role per group. For instance:

User Role Group
Tony Stark owner Stark Industries
Tony Stark member The Avengers

We want to stop Tony from having more than one role per group, i.e. he couldn't be both an owner and a member of Stark Industries. Let's start by running the following migration. Substitute Roles for the name of the table where you need records to be unique:

rails g migration AddUniqueIndexToRoles

Then, find the migration it generates inside your db/migrate folder. Add the following code, and remember to change :user and :group to the names of the columns you want to keep unique:

# xxxxxxxxxxxxxxxxxx_add_unique_index_to_roles.rb
class AddUniqueIndexToRoles < ActiveRecord::Migration[5.2]
  def change
    add_index :roles, [:user, :group], unique: true
  end
end

Finally, in the model, add the following code, remembering again to change :user and :group to the names of the columns you want to keep unique:

# role.rb
class Role < ApplicationRecord
  validates :user, uniqueness: { scope: :group }
end

Now, Tony can only be an owner of Stark Industries, not a member. Congratulations, you've saved the Marvel Universe.