This is the case.
MODEL
User hasOne Info
User
id
username
password
manager_id
Info
id
first_name
last_name
sex
I wanted to generate a list of all Users displaying the first_name, last_name and sex. And I wanted the indexes to be generated with User.id and the display field with this format "Info.last_name, Info.first_name (Info.sex)". I have developed a function to override cakePHP $model->find.
In your app_model.php, you include this function:
class AppModel extends Model {
function find($type, $options = array()) {
switch ($type) {
case 'superlist':
if(!isset($options['format'])) {
$options['format'] = '';
for ($i=0; $i$options['format'] .= "%$i ";
}
$options['format'] = trim($options['format']);
}
if (isset($options['index'])){
preg_match('/(.*?)\.(.*)/', $options['index'], $match);
$index_alias = $match[1];
$index_field = $match[2];
}else{
$index_alias = $this->alias;
$index_field = 'id';
}
$options['fields'] = array_merge(array("{$index_alias}.{$index_field}"), $options['fields']);
$list = $this->find('all', $options);
$result = array();
foreach ($list as $row){
$result[$row[$index_alias][$index_field]] = $options['format'];
foreach ($options['fields'] as $index=>$field){
preg_match('/(.*?)\.(.*)/', $field, $match);
$field_alias = $match[1];
$field_field = $match[2];
$result[$row[$index_alias][$index_field]] =
str_replace('%'.$index, $row[$field_alias][$field_field],
$result[$row[$index_alias][$index_field]]);
}
}
return $result;
break;
default:
return parent::find($type, $options);
break;
}
}
}
This is how you call the generate list function in your controller action.
// if you have not declared hasOne Info in User model, this is needed in order for User model generate Info model with it and you can pass condition on Info fields
$this->User->bindModel(
array(
'hasOne' => array('Info')
)
);
$users = $this->User->find('superlist',
array(
'format' => '%3, %2 (%1)',
'index' => 'User.id', // --> this is the default so you may not pass this option
'fields' =>
array(
'Info.sex', // --> %1
'Info.first_name', // --> %2
'Info.last_name', // --> %3
),
'order' => "Info.first_name, Info.last_name", // -- if you want to sort the option
'condition' => "User.manager_id=2 AND Info.lastname='Smith'", // --> if you need some filtering
)
);
$this->set(compact('users'));
$users array will contain the following structure:
array(
'User.id1' => 'Info.last_name1, Info.first_name1 (Info.sex1)',
'User.id2' => 'Info.last_name2, Info.first_name2 (Info.sex2)',
'User.id3' => 'Info.last_name3, Info.first_name3 (Info.sex3)',
.
.
.
'User.idN' => 'Info.last_nameN, Info.first_nameN (Info.sexN)',
)
Hope this post can help you in your future cakePHP 1.2 development.
Thanks to http://teknoid.wordpress.com/2008/09/04/findlist-with-three-or-combined-fields/ for giving me inspiration to develop this function.