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

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
end

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.


Comments

About Afomi

Afomi is the digital sandbox of Ryan Wold, who is always evolving this to better share inspirations and aspirations.

About Ryan

Ryan is a systems-thinking Product Developer and Designer who practices agile, test-driven, and lean continuous software delivery, while solving problems with people.