Search code examples
cakephpfieldvirtual

CakePHP Join virtualField as displayField


I'm trying to do one of two things, use a virtual field from a model as the display field in my join model, or use the virtual field as the display in a find('list') on my join model.

Here's the current layout:

MODELS

<?php
class Participant extends AppModel {
    public $hasMany = array('Registration');

    public $virtualFields = array(
        'full_name' => 'CONCAT(last_name, ", ", first_name)'
    );

    public $displayField = 'full_name';
}
 -----
class Contest extends AppModel {
    public $hasMany = array('Registration');

}
-----
class Registration extends AppModel {
    public $belongsTo = array('Participant', 'Contest');
    public $hasMany = array('Assignment');

}
?>

Tables are as follows:

participants          contests       registrations
------------          ---------      --------------
id                    id             id
first_name            name           contest_id
last_name                            participant_id

In my contests controller I'm trying to develop a list to be viewed as checkboxes in the view.

Here is the excerpt from my contests controller:

$this->loadModel('Registration');
        $this->set('registrations', $this->Registration->find(
                'list',
                        array(
                            'conditions' => array('contest_id' => $contestId),
                            'recursive' => 1
                        )
            )
        );
//$contestId is defined previously, and I have verified such.

This all actually runs fine as it is, and in the view will display a column of checkboxes with the registration_id as the label next to the checkbox.

I would like to get a full_name as is defined in the Participant model to be the displayField of the Registration model. I've been searching and can't quite seem to find a good way of doing that. I hope I have been descriptive enough, and please let me know if you have any questions and I'll try to explain better. Thank you.

edit: I'm using CakePHP 2.4.


Solution

  • try to add the 'fields' parameter

    $this->loadModel('Registration');
    $this->set('registrations', $this->Registration->find(
        'list',
        array(
            'fields' => array('Registration.id', 'Participant.full_name'),
            'conditions' => array('contest_id' => $contestId),
            'recursive' => 1
        )
    ));
    

    edit: apparently cake does not place virtual fields of associated models when using find() with 'fields' options.

    So you have to build your array by yourself, hoping your models use the containable behavior

    $registrations =  $this->Registration->find(
        'all',
        array(
            'contain' => array(
                'Participant' => array('full_name')
            ),
            'conditions' => array('contest_id' => $contestId),
        )
    );
    $registrations =  Hash::combine($registrations, '{n}.Registration.id', '{n}.Participant.full_name');
    $this->set('registrations', $registrations);