Lookupable Behavior
Posted on 30/8/08 by Felix Geisendörfer
Hey folks,
this is post #11 of my 30 day challenge.
If you ever had to work with a fairly normalized database where for example the statuses of some tables have their own table then you probably know how annoying it can be do keep those status tables in sync with everybody during development. Whenever you create a new status record you need to tell everybody about it. Then you need a good approach to refer to this status in your application and keep your code readable.
So here is what I came up with:
function lookup(&$model, $conditions, $field = 'id', $create = true) {
if (!is_array($conditions)) {
$conditions = array ($model->displayField => $conditions);
}
if (!empty($field)) {
$fieldValue = $model->field($field, $conditions);
} else {
$fieldValue = $model->find($conditions);
}
if ($fieldValue !== false) {
return $fieldValue;
}
if (!$create) {
return false;
}
$model->create($conditions);
if (!$model->save()) {
return false;
}
$conditions[$model->primaryKey] = $model->id;
if (empty($field)) {
return $model->read();
}
return $model->field($field, $conditions);
}
}
The basic idea is to use this behavior with primitive tables that only have an id and a name / title / whatever column. So lets say you have a post_statuses table and you want to assign your current post the status 'Published', things would be as easy as:
This causes the behavior to search your post_statuses table for a record named 'Published'. If it is found then the records id is returned. If it is not found, then the record is created and the new id is returned. This way you never have to worry about keeping your status tables in sync as everything is created on the fly and it is dead simple to expand available status options this way. Of course this method is not going to protect you from typos or people going nuts with adding new statuses, but with a little internal policy on how to use this behavior you should be able to save yourself some time and regain some of that hair you lost because of internet explorer : ).
The latest version of this code along with installation instructions is published in the debuggable scraps repository as always.
Feedback is most welcome! Please leave a comment.
-- Felix Geisendörfer aka the_undefined