Yii-BELONGS_TO VS HAS_ONE
It’s very common to see new Yii users confusing the relations
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.
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 (
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)
// 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
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_TOis where this model owns the linking field
BELONGS_TOreferences the related model’s primary key
HAS_MANYis where the related model owns the linking field
HAS_MANYreference this model’s primary key
- If you define a
BELONGS_TOrelation in one model, you probably want an associated
HAS_MANYrelation in its related mode
- You probably don’t really want