8

Hey I have a model foo that has_one :bar. And bar belongs_to :foo. I was wondering if there is a way to augment the has_one such that no two bars can belong to the same foo. I looked at the documentation for has_one and it seems like there is no :uniq parameter which I am allowed to specify. So do I have to create a custom validation to achieve this? Or is there an easier way?

Thanks.

Ken Ratanachai S.
  • 3,307
  • 34
  • 43
deruse
  • 2,851
  • 7
  • 40
  • 60

3 Answers3

17

You do not need a custom validation, just enforce uniqueness of bar for any given foo

class Bar < ActiveRecord::Base
  belongs_to :foo
  validates_uniqueness_of :foo_id
end
Ken Ratanachai S.
  • 3,307
  • 34
  • 43
Blizzo
  • 662
  • 1
  • 4
  • 11
  • This would ensure that no two foos have the same bar, but @dhruvg is looking to ensure that no two bars belong to the *same* foo. – Stephen Corwin Dec 30 '15 at 05:03
  • As mentioned by @pynix-wang, validation of uniqueness does not guaranty anything in concurrent environments. You should use unique index – Nick Roz Dec 19 '21 at 19:13
3

add a uniq index to foo_id in table bars so you can not create 2 bars with same foo_id, so only one bar can belongs to foo

Pynix Wang
  • 41
  • 2
  • 1
    `validates_uniqueness_of` may not uniq in a concurrency environment. – Pynix Wang Jun 12 '18 at 15:59
  • you might also need to create a unique index and/or a foreign key constraint on the supplier column for the accounts table.[From Rails Guide](http://guides.rubyonrails.org/association_basics.html#the-has-one-association) – Pynix Wang Jun 12 '18 at 16:06
0

I think you should write your own validation, because two different record of Foo has no idea about others related record (Bar)

bor1s
  • 4,081
  • 18
  • 25
  • Irrelevent. That would be of concern if he wanted no two Foo's to have the same Bar. But that's not what he asked. – elc May 03 '12 at 16:46