Search code examples
mysqlruby-on-railspostgresqlactiverecordrails-migrations

Rails Unique Constraints Model + Database Level and Race Conditions


I currently have the following migration for my UserGroups has_many :through association:

class CreateUserGroups < ActiveRecord::Migration
  def change
    create_table :user_groups do |t|
      t.integer :user_id, :null => false
      t.integer :group_id, :null => false
      t.timestamps null: false
    end
  end
end

With the following model and unique constraint:

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
  validates_uniqueness_of :user, :scope => :group, :message => :not_unique
end

The uniqueness validation is working great, but what if competing threads in my application cause a race condition and it makes past the application-level check? How can I write a migration to protect against a duplicate row in my join table for users and groups at the database level?


Solution

  • You need to add an unique index

    add_index :user_groups, [:user_id, :group_id], unique: true