# one-to-one  relationship

**URL:** <https://discuss.rubyonrails.org/t/one-to-one-relationship/61845>\
**Category:** rubyonrails-talk\
**Created:** [December 1, 2011, 9:59pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845 "2011-12-01T21:59:36Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 1, 2011, 9:59pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/1 "2011-12-01T21:59:36Z")

</div>

Is it wrong to use a beings\_to on both side of a one-to-one association ?

User belongs\_to :account so I have an account\_id field

Account belongs\_to :owner, :class\_name =\> 'User', :foreign\_key =\> 'user\_id'

I can get user.account and account.owner It runs, but I wonder about any collateral effect...

thanks for your feedback

---

<div class="post-metadata">

**Author:** ![Everaldo\_Gomes](https://avatars.discourse-cdn.com/v4/letter/e/ea5d25/32.png) [@Everaldo\_Gomes](https://discuss.rubyonrails.org/u/Everaldo_Gomes)\
**Post date:** [December 1, 2011, 10:01pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/2 "2011-12-01T22:01:31Z")

</div>

I think it’s fine.

Best Regards,

Everaldo

---

<div class="post-metadata">

**Author:** ![rab](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/rab/32/710_2.png) [@rab](https://discuss.rubyonrails.org/u/rab)\
**Post date:** [December 1, 2011, 10:29pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/3 "2011-12-01T22:29:47Z")

</div>

Which one do you create first? What foreign key value does it get? Do you always do the create/create/update in a transaction?

Do you ever (ever!) have one without the other?

class User \< ActiveRecord::Base

has\_one :account

end

class Account \< ActiveRecord::Base

belongs\_to :owner, :class\_name =\> ‘User’, :foreign\_key =\> ‘user\_id’

end

I think that current versions of ActiveRecord have the right default for the foreign key (which is the \_id after the class name rather than the association name), but specifying it works just fine, of course.

-Rob

Rob Biedenharn

[Rob@AgileConsultingLLC.com](mailto:Rob@AgileConsultingLLC.com)[http://AgileConsultingLLC.com/](http://AgileConsultingLLC.com/)

[rab@GaslightSoftware.com](mailto:rab@GaslightSoftware.com)[http://GaslightSoftware.com/](http://GaslightSoftware.com/)

---

<div class="post-metadata">

**Author:** ![Peter\_Vandenabeele1](https://avatars.discourse-cdn.com/v4/letter/p/59ef9b/32.png) [@Peter\_Vandenabeele1](https://discuss.rubyonrails.org/u/Peter_Vandenabeele1)\
**Post date:** [December 1, 2011, 10:32pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/4 "2011-12-01T22:32:20Z")

</div>

I don’t like it (if I understand correctly that you have both

in users table account\_id

in accounts table user\_id)

1. This code expresses the 1-on-1 link between

a user and his associated account 2 times

(user.account\_id points to [account.id](http://account.id) and

account.user\_id point to [user.id](http://user.id)).

So, there is a chance that the 2 links go out of sync.

1. You will always need 3 database writes to save

a pair of a user and an account.

If you did:

class User

belongs\_to :account

end

class Account

has\_one :user

end

you could write

account = Account.new(params[:account])

user = account.build\_user(params[:user])

account.save # handle the return value

and this will do all that is required (with 2 database writes,

first the account, which will render the [account.id](http://account.id) and then

user will will be saved with user.account\_id = [account.id](http://account.id)).

But with the original code (with 2 belongs\_to associations),

I think you will need to do 3 writes:

- account.save (#=\> [account.id](http://account.id))

- user.save (with user.account\_id = [account.id](http://account.id))

- a second account.save (for updating account.user\_id = [user.id](http://user.id))

I fail to see the advantage over a symmetric belongs\_to , has\_one

relationship.

Also check out the advantages of the inverse\_of

class User

belongs\_to :account, :inverse\_of =\> :user

end

class Account

has\_one :user, :inverse\_of =\> :account

end

This will make sure the user.account is known before the save.

With the :inverse\_of, this is the case:

$ rails c

Loading development environment (Rails 3.1.1)

001:0\> u = User.new(:name =\> “peter”)

=\> #\<User id: nil, name: “peter”, account\_id: nil, created\_at: nil, updated\_at: nil\>

002:0\> a = u.build\_account(:number =\> “123”)

=\> #\<Account id: nil, number: “123”, created\_at: nil, updated\_at: nil\>

003:0\> a.user

=\> #\<User id: nil, name: “peter”, account\_id: nil, created\_at: nil, updated\_at: nil\>

004:0\> u.save

(0.4ms) BEGIN

SQL (50.1ms) INSERT INTO “accounts” (“created\_at”, “number”, “updated\_at”) VALUES ($1, $2, $3) RETURNING “id” [[“created\_at”, Thu, 01 Dec 2011 22:24:16 UTC +00:00], [“number”, “123”], [“updated\_at”, Thu, 01 Dec 2011 22:24:16 UTC +00:00]]

SQL (1.6ms) INSERT INTO “users” (“account\_id”, “created\_at”, “name”, “updated\_at”) VALUES ($1, $2, $3, $4) RETURNING “id” [[“account\_id”, 1], [“created\_at”, Thu, 01 Dec 2011 22:24:16 UTC +00:00], [“name”, “peter”], [“updated\_at”, Thu, 01 Dec 2011 22:24:16 UTC +00:00]]

(0.9ms) COMMIT

=\> true

Without the inverse\_of relations, this is the result:

$ rails c

Loading development environment (Rails 3.1.1)

001:0\> u = User.new(:name =\> “peter”)

=\> #\<User id: nil, name: “peter”, account\_id: nil, created\_at: nil, updated\_at: nil\>

002:0\> a = u.build\_account(:number =\> “123”)

=\> #\<Account id: nil, number: “123”, created\_at: nil, updated\_at: nil\>

003:0\> a.user

=\> nil

004:0\> # the “back link is only known AFTER the save to db and a reload :-/”

005:0\* ^C

005:0\> u.save

(0.4ms) BEGIN

SQL (16.1ms) INSERT INTO “accounts” (“created\_at”, “number”, “updated\_at”) VALUES ($1, $2, $3) RETURNING “id” [[“created\_at”, Thu, 01 Dec 2011 22:28:35 UTC +00:00], [“number”, “123”], [“updated\_at”, Thu, 01 Dec 2011 22:28:35 UTC +00:00]]

SQL (1.3ms) INSERT INTO “users” (“account\_id”, “created\_at”, “name”, “updated\_at”) VALUES ($1, $2, $3, $4) RETURNING “id” [[“account\_id”, 2], [“created\_at”, Thu, 01 Dec 2011 22:28:35 UTC +00:00], [“name”, “peter”], [“updated\_at”, Thu, 01 Dec 2011 22:28:35 UTC +00:00]]

(0.8ms) COMMIT

=\> true

006:0\> a.user

=\> nil

007:0\> a.reload

Account Load (1.4ms) SELECT “accounts”.\* FROM “accounts” WHERE “accounts”.“id” = $1 LIMIT 1 [[“id”, 2]]

=\> #\<Account id: 2, number: “123”, created\_at: “2011-12-01 22:28:35”, updated\_at: “2011-12-01 22:28:35”\>

008:0\> a.user

User Load (1.0ms) SELECT “users”.\* FROM “users” WHERE “users”.“account\_id” = 2 LIMIT 1

=\> #\<User id: 2, name: “peter”, account\_id: 2, created\_at: “2011-12-01 22:28:35”, updated\_at: “2011-12-01 22:28:35”\>

009:0\> # work-around (when inverse\_of is not available)

010:0\* ^C

010:0\> u3 = User.new(:name =\> “peter”)

=\> #\<User id: nil, name: “peter”, account\_id: nil, created\_at: nil, updated\_at: nil\>

011:0\> a3 = u3.build\_account(:number =\> ‘456’, :user =\> u3)

(0.4ms) BEGIN

(0.3ms) COMMIT

=\> #\<Account id: nil, number: “456”, created\_at: nil, updated\_at: nil\>

012:0\> a3.user

=\> #\<User id: nil, name: “peter”, account\_id: nil, created\_at: nil, updated\_at: nil\>

013:0\>

HTH,

Peter

---

<div class="post-metadata">

**Author:** ![11155](https://avatars.discourse-cdn.com/v4/letter/1/d26b3c/32.png) [@11155](https://discuss.rubyonrails.org/u/11155)\
**Post date:** [December 1, 2011, 10:35pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/5 "2011-12-01T22:35:23Z")

</div>

Kad Kerforn wrote in post #1034622:

> Is it wrong to use a beings\_to on both side of a one-to-one association ?
> 
> User belongs\_to :account so I have an account\_id field
> 
> Account belongs\_to :owner, :class\_name =\> 'User', :foreign\_key =\> 'user\_id'
> 
> I can get user.account and account.owner It runs, but I wonder about any collateral effect...
> 
> thanks for your feedback

belongs\_to should be on the side of a one-to-one association that contains the foreign key (same as a one-to-many).

The other side (the side without a foreign key should use has\_one NOT belongs to.

User has\_one :account

Account belongs\_to :owner, :class\_name =\> 'User', :foreign\_key =\> 'user\_id'

Or you could use the standard conventions:

Account belongs\_to :user

---

<div class="post-metadata">

**Author:** ![Everaldo\_Gomes](https://avatars.discourse-cdn.com/v4/letter/e/ea5d25/32.png) [@Everaldo\_Gomes](https://discuss.rubyonrails.org/u/Everaldo_Gomes)\
**Post date:** [December 1, 2011, 10:41pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/6 "2011-12-01T22:41:15Z")

</div>

> Kad Kerforn wrote in post #1034622:
> 
> > Is it wrong to use a beings\_to on both side of a one-to-one
> 
> > association ?
> 
> > 
> 
> > User
> 
> > belongs\_to :account so I have an account\_id field
> 
> > 
> 
> > Account
> 
> > belongs\_to :owner, :class\_name =\> ‘User’, :foreign\_key =\> ‘user\_id’
> 
> > 
> 
> > I can get user.account and account.owner
> 
> > It runs, but I wonder about any collateral effect…
> 
> > 
> 
> > thanks for your feedback

> belongs\_to should be on the side of a one-to-one association that
> 
> contains the foreign key (same as a one-to-many).
> 
> The other side (the side without a foreign key should use has\_one NOT
> 
> belongs to.

I think I didn’t thought enough before reply. =)

Good arguments, guys!

---

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 2, 2011, 11:35pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/7 "2011-12-02T23:35:32Z")

</div>

Thanks ... it runs , but as mentioned it has some side effects.... even if I cannot have one side wo the other one ... learn a lot about collateral effects...

---

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 2, 2011, 11:35pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/8 "2011-12-02T23:35:56Z")

</div>

Thanks ... it runs , but as mentioned it has some side effects.... even if I cannot have one side wo the other one ... learn a lot about collateral effects...

---

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 2, 2011, 11:36pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/9 "2011-12-02T23:36:26Z")

</div>

Thanks ... it runs , but as mentioned it has some side effects.... even if I cannot have one side wo the other one ... learn a lot about collateral effects...

---

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 2, 2011, 11:36pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/10 "2011-12-02T23:36:38Z")

</div>

Thanks ... it runs , but as mentioned it has some side effects.... even if I cannot have one side wo the other one ... learn a lot about collateral effects...

---

<div class="post-metadata">

**Author:** ![Erwin1](https://avatars.discourse-cdn.com/v4/letter/e/d07c76/32.png) [@Erwin1](https://discuss.rubyonrails.org/u/Erwin1)\
**Post date:** [December 2, 2011, 11:37pm UTC](https://discuss.rubyonrails.org/t/one-to-one-relationship/61845/11 "2011-12-02T23:37:17Z")

</div>

Got a clear understanding on what to do and not to do even if it works ...
