5
votes

I've got a model Employee which belongsTo an Address-model. When I fetch data from the Employees model, the associated Address record gets fetched too. Additionally, the Address model has a virtualField full_name. This looks like this:

Array 
(
[0] => Array
       (
        [Employee] => Array
            (
                [id] => 1
                [address_id] => 33
                [username] => ...
                ...
            )

        [Address] => Array
            (
                [id] => 33
                [firstname] => Blah
                [full_name] => Blah Blubb
                ...
            )

    )

[1] => Array  (
        [Employee] => Array   (
                [id] => 2
                ...

I want to have included this virtualField in the Employee part of the data array too, like

Array (
[0] => Array (
        [Employee] => Array
            (
                [id] => 1
                [full_name] => Blah Blubb
                ...
            )

Tis isn't possible to solve by just adding

$virtualFields = array(
    'full_name' => 'CONCAT_WS(" ", Address.firstname, Address.surname)',
);

to the Employees model, as the Cookbook states There is a solution proposed ("copy virtualFields from one model to another at runtime when you need to access them"), but I don't understand this solution. Where do I have to place this? In the controller? In the model in the find function?

Thanks for Help

3

3 Answers

4
votes

http://book.cakephp.org/view/1608/Virtual-fields#Virtual-fields-and-model-aliases-1632

The implementation of virtualFields in 1.3 has a few limitations. First you cannot use virtualFields on associated models for conditions, order, or fields arrays. Doing so will generally result in an SQL error as the fields are not replaced by the ORM. This is because it's difficult to estimate the depth at which an associated model might be found.

2
votes

I'm doing this by hand now in the afterFind model callback function:

array_walk($results,function(&$a){
        if(isset($a['Address']['full_name'])) {
            $a['Employee']['full_name'] = $a['Address']['full_name'];
            unset($a['Address']);
        }
    });

Might be it's not nice, but it works.

1
votes

Add the following to your model:

public function __construct($id=false,$table=null,$ds=null){
    parent::__construct($id,$table,$ds);
    $this->virtualFields = array(
        'full_name'=>"CONCAT(`Address.firstname`,' ',`Address.surname`)"
    );
}