Difference between #4 and #3 of Relations: BELONGS_TO versus HAS_ONE

unchanged
Title
Relations: BELONGS_TO versus HAS_ONE
unchanged
Category
FAQs
unchanged
Tags
relations, HAS_ONE, BELONGS_TO
changed
Content
It's very common to see new Yii users confusing the relations `HAS_ONE` and
`BELONGS_TO`, and getting it wrong means you won't get proper values back. And
though we'll talk about `HAS_MANY` as well, we're specifically omitting the
`MANY_MANY` relation because it's a whole different animal.

Both `BELONGS_TO` and `HAS_ONE` are about linking two models together, and sound
like the same thing, but they link in essentially opposite directions. Let's
illustrate with three simple tables, each of which has a primary key of
`id`,(`id`), and a number of linking fields (`user_id`) that
reference the User table.
~~~
USER table
- id 
- name

POST table
 - id
 - user_id         REFERENCES User.id
 - content

PROFILE table
 - id
 - user_id         REFERENCES User.id
 - profile_info
~~~
**KEY POINT**: A `BELONGS_TO` relation says that a field in **this** model
points to the primary key in **another** model; in this case, _the current model
owns the linking field_.

**KEY POINT**: A `HAS_ONE` relation says that some **other** model has a linking
field pointing to **this** model's primary key; in this case, _the related model
owns the linking field_.

Let's put these in context (numbered for reference)
~~~
[php]
// Post model relations
1.   'user'    => array(self::BELONGS_TO, 'User',    'user_id'),

// Profile model relations
2.   'user'    => array(self::BELONGS_TO, 'User',    'user_id'),

// User model relations
3.   'posts'   => array(self::HAS_MANY,   'Post',    'user_id'),
4.   'profile' => array(self::HAS_ONE,    'Profile', 'user_id'),
~~~
Relations 1 has the linking field `user_id` in **this** model, pointing to the
primary key of the **related** model `User`. Likewise with relation #2.

Relations 3 and 4 are essentially the same thing as each other: the linking
field `user_id` is not in **this** model, but in the **related** model, and the
primary key involved is in **this** model (`User`). The difference is that
`HAS_MANY` returns an array of possibly multiple objects, while `HAS_ONE`
returns a single object.

`HAS_ONE` is just a special case of `HAS_MANY`, and the circumstances where
`HAS_ONE` makes sense are far more limited than `HAS_MANY` and `BELONGS_TO`.

Some points to remember:

* When defining one of these relations, you don't ever name the primary key; Yii
figures it out from the DB schema
* `BELONGS_TO` is where **this** model owns the linking field
* `BELONGS_TO` references the **related** model's primary key
* `HAS_ONE`/`HAS_MANY` is where the **related** model owns the linking field
* `HAS_ONE`/`HAS_MANY` reference **this** model's primary key
* If you define a `BELONGS_TO` relation in one model, you probably want an
associated `HAS_MANY` relation in its related mode
* You probably don't really want `HAS_ONE` ever