Difference between #2 and #7 of
Relations: BELONGS_TO versus HAS_ONE

Changes

Title unchanged

Relations: BELONGS_TO versus HAS_ONE

Category unchanged

FAQs

Yii version unchanged

Tags unchanged

relations, HAS_ONE, BELONGS_TO

Content changed

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`), and a number of linking fields (`user_id`) that reference the User table.
~~~
USER table
[...]
- 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_.
 
 
We can thik that a PARENT table will be the one that doesn't have a foreign key, and a CHILD table as the one who "depends" on the parent table, that is, it has a foreign key.
 
 
Given that, a CHILD BELONGS_TO a PARENT and a PARENT HAS_ONE CHILD
.

Let's put these in context (numbered for reference)
[...]
```php
// Post model relations
1. 'user' => array(self::BELONGS_TO, 'User', 'user_id'),
 
// Post belongs_to a user, because it is a child table.
// Profile model relations 2. 'user' => array(self::BELONGS_TO, 'User', 'user_id'),  
// Profile belongs_to a user, because it is a child table.
// User model relations 3. 'posts' => array(self::HAS_MANY, 'Post', 'user_id'), // User has_many posts, because User is a parent table.
 
4. 'profile' => array(self::HAS_ONE, 'Profile', 'user_id'), // User has_one profile, because User is a parent table.
 
```
 
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`.


 
**Weird example**
 
 
~~~
 
USER table
 
- id 
 
- name
 
- status_id         REFERENCES status.id
 
 
STATUS table
 
 - id
 
 - name
 
~~~
 
 
Here one would think in human terms that a USER HAS_ONE STATUS. But that doesn't work. As you see, the USER is in fact a "child" table of STATUS, because it is referencing it, it depends on it. So the relations would be:
 
 
 
```php 
// User model relations
 
1.   'status'    => array(self::BELONGS_TO, 'Status',    'status_id'),
 
// User belongs_to a status, because it is a child table.
 
 
// Status model relations
 
2.   'users'    => array(self::HAS_MANY, 'User',    'status_id'),
 
// Status has_many users, because it is a parent table.
 
```
 
 
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
[...]
56 0
35 followers
Viewed: 164 737 times
Version: 1.1
Category: FAQs
Written by: Steve Friedl
Last updated by: Jorgee
Created on: Apr 26, 2011
Last updated: 11 years ago
Update Article

Revisions

View all history