Gold Apple Software Web Development by Geoff Appleby

CakePHP HasOne - BelongsTo Relationship Keys

The common pattern in CakePHP is to give each table a Primary, Auto Incrementing `id` column, but when utilizing HasOne and BelongsTo relationships between two models this column is superflous and can make tracing downstream relationships more difficult. For example, when splitting data between User and Profile models, giving the profile it's own `id` column adds no useful information since the `user_id` column will by definition be a unique reference to a user.  The auto increment values may remain in sync and give you two columns of duplicate data, but if they diverge models related to the profile (e.g. ProfilePhoto) now lose their direct association with the user model. It is relatively easy though to modify the models and clean things up.

Since CakePHP allows you to modify the primary key field of a model, you can set the Profile model's foreign key to the User model as Profile's own primary key.  Since this column is dependent on the User primary key, the database column is set as the primary key but not to autoincrement.

class User extends AppModel {
var $hasOne = array('Profile');
}

class Profile extends AppModel {
var $primaryKey = 'user_id';
var $belongsTo = array('User');
var $hasMany = array('ProfilePhoto');
}

The only caveat to remember is that you can no longer rely on the database to set the id for a profile model when saving.  You must specify it's value or pass the related User model data to save methods, but in this instance you wouldn't be creating a profile without a related user already existing or being created at the same time anyways.

Further related models are unchanged, and still reference the Profile model via a `profile_id` field, but it is now known that anything referencing a Profile model can reference the related User model with the same key value, potentially saving some extra joins in some cases.

class ProfilePhoto extends AppModel {
var $belongsTo = array('Profile');
}

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <br> <p>
  • Lines and paragraphs break automatically.
  • Each email address will be obfuscated in a human readable fashion or (if JavaScript is enabled) replaced with a spamproof clickable link.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.