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