Jackson Cunningham
Jackson Cunningham

Reputation: 5073

Rails: validate uniqueness of two columns (together)

I have a Release model with medium and country columns (among others). There should not be releases that share identical medium/country combinations.

How would I write this as a rails validation?

Upvotes: 207

Views: 113022

Answers (3)

Aamir
Aamir

Reputation: 16957

All the above answers are missing how to validate the uniqueness of multiple attributes in a model. The code below intends to tell how to use multiple attributes in a scope.

validates :country, uniqueness: { scope: [:medium, :another_medium] }

It validates uniqueness of country in all rows with values of medium and another_medium.

Note: Don't forget to add an index on the above column, this insures fast retrieval and adds a DB level validation for unique records.

Update: For adding an index while creating table

t.index [:country, :medium, :another_medium], unique: true

Upvotes: 135

tompave
tompave

Reputation: 12402

You can use a uniqueness validation with the scope option.

Also, you should add a unique index to the DB to prevent new records from passing the validations when checked at the same time before being written:

class AddUniqueIndexToReleases < ActiveRecord::Migration
  def change
    add_index :releases, [:country, :medium], unique: true
  end
end



class Release < ActiveRecord::Base
  validates :country, uniqueness: { scope: :medium }
end

Upvotes: 353

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34308

You can pass a :scope parameter to your validator like this:

validates_uniqueness_of :medium, scope: :country

See the documentation for some more examples.

Upvotes: 53

Related Questions