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

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:

UserRoleGroup
Tony StarkownerStark Industries
Tony StarkmemberThe 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.

Mark @mtmdev_