skimberk1
skimberk1

Reputation: 2094

Validate that two columns are unique themselves and from each other

I'm working an a Rails application where when a user creates a product, that product is given a random url in the column original_url. The user can later pick a custom url, which will be saves in custom_url.

The product will be able to be accessed from both the original url and the custom url. I just can't figure out how to keep the columns not only unique amongst themselves, but also amongst each other. I did discover :scope, but that doesn't achieve what I have in mind.

Example of what can't happen:

original_url: Ab | custom_url: nil

original_url: Bc | custom_url: Ab

Another example of what can't happen:

original_url: Ab | custom_url: nil

original_url: Ab | custom_url: nil

Example of what can happen:

original_url: Ab | custom_url: nil

original_url: Bc | custom_url: De

original_url: Gh | custom_url: nil

Upvotes: 0

Views: 60

Answers (2)

Billy Chan
Billy Chan

Reputation: 24815

A super simple hack is to add a unique prefix to original_url and custom_url

Say, your original original_url is 6 digits, like 'foobar', then the new origina_url will be 'ofoobar'. And custom_url, if generated, should start with "c" which is "cfoobar".

By this you only need to validate origina_url and custom_url separately and normally, only add a pattern to fit the prefix.

Upvotes: 1

Yanhao
Yanhao

Reputation: 5294

Maybe the best choice is to write a customized validation block/method, like:

validate do
  if Product.where(original_url: original_url, custom_url: original_url).size > 0 ||
    Product.where(original_url: custom_url, custom_url: custom_url).size > 0
  errors.add(:base, 'Original url and custom url must be unique.')
end

Another solution is to create a model for urls, then let Product has_many :urls.

Upvotes: 1

Related Questions