Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between belongs_to and has_one?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile, then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user. To determine who "has" the other object, look at where the foreign key is. We can say that a User "has" a Profile because the profiles table has a user_id column. If there was a column called profile_id on the users table, however, we would say that a Profile has a User, and the belongs_to/has_one locations would be swapped.

here is a more detailed explanation.


It's about where the foreign key sits.

class Foo < AR:Base
end
  • If foo belongs_to :bar, then the foos table has a bar_id column
  • If foo has_one :bar, then the bars table has a foo_id column

On the conceptual level, if your class A has a has_one relationship with class B then class A is the parent of class B hence your class B will have a belongs_to relationship with class A since it is the child of class A.

Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class declaring the belongs_to relationship.

class User < ActiveRecord::Base
  # I reference an account.
  belongs_to :account
end

class Account < ActiveRecord::Base
  # One user references me.
  has_one :user
end

The tables for these classes could look something like:

CREATE TABLE users (
  id int(11) NOT NULL auto_increment,
  account_id int(11) default NULL,
  name varchar default NULL,
  PRIMARY KEY  (id)
)

CREATE TABLE accounts (
  id int(11) NOT NULL auto_increment,
  name varchar default NULL,
  PRIMARY KEY  (id)
)

has_one and belongs_to generally are same in a sense that they point to the other related model. belongs_to make sure that this model has the foreign_key defined. has_one makes sure that the other model has_foreign key defined.

To be more specific, there are two sides of relationship, one is the Owner and other is Belongings. If only has_one is defined we can get its Belongings but cannot get the Owner from the belongings. To trace the Owner we need to define the belongs_to as well in the belonging model.


One additional thing that I want to add is, suppose we have the following models association.

class Author < ApplicationRecord
  has_many :books
end

If we only write the above association, then we can get all books of a particular author with

@books = @author.books

but, for a particular book, we can't get the corresponding author with

@author = @book.author

To make the above code work we need to add an association to the Book model as well, like this

class Book < ApplicationRecord
  belongs_to :author
end

This will add method 'author' to the Book model. For mode details see guides


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!