A civic-minded citizen seeking the singularity

An entry

When using Rails, ensure uniqueness at the data-store level

Date: 2017-12-11
Status: release
Tags: rails postgresql

Rails models offer methods to enforce uniqueness and such. Unfortunately, Rails is often run on several processes at once, and the processes don't share state by design, so concurrent requests pass uniqueness validation because the data hasn't been persisted in the data store below. A classic race condition.

This is is a well-known and written about issue. Accordingly the answer is pretty straight forward. Adding a UNIQUE constraint on the table directly.

rails g migration add_uniqueness_constraint

# In the migration
def change
  add_index :people, [:column_1, :column_2], unique: true

I ran this on my knowingly duplicative data and got a failure when running the migration, as expected. I resolved the data issue manually via the rails console. Then, I re-ran the migration, and it completed successfully.

I tested the app, and it worked! Now Rails has a back up plan. Bumpers.