3.7.6.2 hasOne
Let’s set up a User model with a hasOne relationship to a Profile model.
First, your database tables need to be keyed correctly. For a hasOne relationship to work, one table has to contain a foreign key that points to a record in the other. In this case the profiles table will contain a field called user_id. The basic pattern is:
| Relation | Schema |
|---|---|
| Apple hasOne Banana | bananas.apple_id |
| User hasOne Profile | profiles.user_id |
| Doctor hasOne Mentor | mentors.doctor_id |
The User model file will be saved in /app/models/user.php. To define the ‘User hasOne Profile’ association, add the $hasOne property to the model class. Remember to have a Profile model in /app/models/profile.php, or the association won’t work.
<?php
class User extends AppModel {
var $name = 'User';
var $hasOne = 'Profile';
}
?>
<?phpclass User extends AppModel {var $name = 'User';var $hasOne = 'Profile';}?>
There are two ways to describe this relationship in your model files. The simplest method is to set the $hasOne attribute to a string containing the classname of the associated model, as we’ve done above.
If you need more control, you can define your associations using array syntax. For example, you might want to limit the association to include only certain records.
<?php
class User extends AppModel {
var $name = 'User';
var $hasOne = array(
'Profile' => array(
'className' => 'Profile',
'conditions' => array('Profile.published' => '1'),
'dependent' => true
)
);
}
?>
<?phpclass User extends AppModel {var $name = 'User';var $hasOne = array('Profile' => array('className' => 'Profile','conditions' => array('Profile.published' => '1'),'dependent' => true));}?>
Possible keys for hasOne association arrays include:
- className: the classname of the model being associated to the current model. If you’re defining a ‘User hasOne Profile’ relationship, the className key should equal ‘Profile.’
- foreignKey: the name of the foreign key found in the other model. This is especially handy if you need to define multiple hasOne relationships. The default value for this key is the underscored, singular name of the current model, suffixed with ‘_id’. In the example above it would default to 'user_id'.
- conditions: An SQL fragment used to filter related model records. It’s good practice to use model names in SQL fragments: “Profile.approved = 1” is always better than just “approved = 1.”
- fields: A list of fields to be retrieved when the associated model data is fetched. Returns all fields by default.
- dependent: When the dependent key is set to true, and the model’s delete() method is called with the cascade parameter set to true, associated model records are also deleted. In this case we set it true so that deleting a User will also delete her associated Profile.
Once this association has been defined, find operations on the User model will also fetch a related Profile record if it exists:
//Sample results from a $this->User->find() call.
Array
(
[User] => Array
(
[id] => 121
[name] => Gwoo the Kungwoo
[created] => 2007-05-01 10:31:01
)
[Profile] => Array
(
[id] => 12
[user_id] => 121
[skill] => Baking Cakes
[created] => 2007-05-01 10:31:01
)
)
