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 abar_id
column - If foo
has_one :bar
, then the bars table has afoo_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.