Josh Smith
Josh Smith

Reputation: 15028

How to avoid a race condition when validating uniqueness across two tables in Rails

This question discusses validating uniqueness across two tables, and the accepted answer mentions "that such code level unique constraints may not work in a race condition among parallel requests unless somehow this can be done at database level."

That is, if you have a User and an Organization and were to validate a unique slug across both, how do you ensure this at the database level, or otherwise avoid the possibility of a race condition arising?

My only thought would be to create a related record like Slug, which belongs_to both models. You would wrap create and update of these models in a transaction where you also create the associated record. This record isn't used for anything except ensuring the additional uniqueness constraint and raising an error at the database level if this is violated.

Is there a better approach or am I on the right path?

Upvotes: 3

Views: 1368

Answers (1)

markets
markets

Reputation: 7033

I'd go with something similar, but adding a DB constraint to ensure the "uniqueness" of those slugs. So, in summary:

  • a polymorphic model Slug: belongs_to :sluggable, polymorphic: true
  • a transaction to control creation (or rollback) of the associated model
  • a constraint at DB layer to ensure uniqueness: add_index :slugs, :slug, unique: true

Upvotes: 2

Related Questions