# Has\_one() in AR kind of weak?

**URL:** <https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397>\
**Category:** Rails\
**Created:** [November 18, 2006, 10:14am UTC](https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397 "2006-11-18T10:14:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Peter\_SSSgjfc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b38774/32.png) [@Peter\_SSSgjfc](https://www.ruby-forum.com/u/Peter_SSSgjfc)\
**Post date:** [November 18, 2006, 10:14am UTC](https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397/1 "2006-11-18T10:14:20Z")

</div>

Hi,

suppose I’m doing a rails system for the DMV.

The rules say:

A person may have 0 or 1 Drivers License.

So, I’d have these 2 tables:

class CreatePeople \< ActiveRecord::Migration  
def self.up  
create\_table :people do |t|  
t.column :name, :string  
end  
end

def self.down  
drop\_table :people  
end  
end

class CreateDriverslicenses \< ActiveRecord::Migration  
def self.up  
create\_table :driverslicenses do |t|  
t.column :person\_id, :integer  
end  
end

def self.down  
drop\_table :driverslicenses  
end  
end

And these models:

class Person \< ActiveRecord::Base  
has\_one :driverslicense  
end

class DriversLicense \< ActiveRecord::Base  
belongs\_to :person  
end

What is the best way to enforce this rule:

A person may have 0 or 1 Drivers License.  
??

I ran a simple test with console:

> > pete = Person.new  
> > =\> #\<Person:0x2364d9c @attributes={“name”=\>nil}, @new\_record=true\>  
> > pete.name = ‘Pete’  
> > =\> “Pete”

> > dl1 = Driverslicense.new  
> > =\> #\<Driverslicense:0x235ac0c @attributes={“person\_id”=\>nil},  
> > @new\_record=true\>

> > dl1.person\_id = pete  
> > =\> #\<Person:0x2364d9c @errors=#\<ActiveRecord::Errors:0x23511ac  
> > @errors={}, @base=#\<Person:0x2364d9c …\>\>,  
> > @attributes={“name”=\>“Pete”, “id”=\>1}, @new\_record=false\>

> > dl1.person.name  
> > =\> “Pete”

So, now Pete has a drivers license.

Let’s try to give him another drivers license:

> > dl2 = Driverslicense.new  
> > =\> #\<Driverslicense:0x233de2c @attributes={“person\_id”=\>nil},  
> > @new\_record=true\>  
> > dl2.person\_id = pete  
> > =\> #\<Person:0x2364d9c @errors=#\<ActiveRecord::Errors:0x23511ac  
> > @errors={}, @base=#\<Person:0x2364d9c …\>\>,  
> > @attributes={“name”=\>“Pete”, “id”=\>1}, @new\_record=false\>

> > dl2.person.name  
> > =\> “Pete”

It appears that dmv has assigned 2 drivers licenses to Pete.

Is it up to me to ‘strengthen’ the has\_one() method in AR?

Here is info about my rails:

$ script/about  
About your application’s environment  
Ruby version 1.8.4 (powerpc-darwin7.9.0)  
RubyGems version 0.9.0  
Rails version 1.1.6  
Active Record version 1.14.4  
Action Pack version 1.12.5  
Action Web Service version 1.1.6  
Action Mailer version 1.2.5  
Active Support version 1.3.1

-Pete  
[http://GoodJobFastCar.com](http://GoodJobFastCar.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Peter\_SSSgjfc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b38774/32.png) [@Peter\_SSSgjfc](https://www.ruby-forum.com/u/Peter_SSSgjfc)\
**Post date:** [November 18, 2006, 10:32am UTC](https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397/2 "2006-11-18T10:32:21Z")

</div>

You could add a uniqueness validation on the Driverslicense model

class Driverslicense \< ActiveRecord::Base  
validates\_uniqueness\_of :person\_id  
end

-Jonathan.

---

<div class="post-metadata">

**Author:** ![Peter\_SSSgjfc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b38774/32.png) [@Peter\_SSSgjfc](https://www.ruby-forum.com/u/Peter_SSSgjfc)\
**Post date:** [November 18, 2006, 12:19pm UTC](https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397/3 "2006-11-18T12:19:18Z")

</div>

In addition to validates\_uniqueness\_of your database probably has an  
option to enforce this kind of thing (eg add a unique index to the  
person\_id column of driver\_licenses

Fred

---

<div class="post-metadata">

**Author:** ![Peter\_SSSgjfc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b38774/32.png) [@Peter\_SSSgjfc](https://www.ruby-forum.com/u/Peter_SSSgjfc)\
**Post date:** [November 18, 2006, 6:28pm UTC](https://www.ruby-forum.com/t/has-one-in-ar-kind-of-weak/76397/4 "2006-11-18T18:28:04Z")

</div>

Peter S. [gjfc] wrote:

> It appears that dmv has assigned 2 drivers licenses to Pete.
> 
> Is it up to me to ‘strengthen’ the has\_one() method in AR?

Hi Pete

The associations methods (has\_one, belongs\_to, etc) do not do any  
validation. They simply create meta-programmed accessor methods on your  
model classes that know how to query the DB for associated objects.

Considering has\_one vs. has\_many, the name of the accessor is affected  
by the association method as well. In your case, Person.has\_one  
:drivers\_license will create an accessor “drivers\_license” on your  
Person class (in memory). If you had used has\_many, an accessor named  
“drivers\_licenses” would have been created instead. Another difference  
is that, though the same finder SQL will be used regardless of whether  
you use has\_one or has\_many, the has\_one finder will only return the  
first matching record, whereas the has\_many will return all matching  
results.

As for ensuring that a has\_one association is enforced, a good practice  
is to define a unique index or key on your DB:

If A has\_one B, then a unique index should be defined on B’s foreign key  
into A (eg. B.A\_id ).

Hope this helps.
