Faiyaz Alam Faiyaz Alam - 4 months ago 39
MySQL Question

How to create a virtual field with containable behavior in cakephp 2.6

I have this code in model User:

$hasOne = array(
'Member' => array(
'className' => 'Member',
'foreignKey' => 'user_id',
'dependent' => true
)
);


function rest_findUserById($id = NULL) {
$row = $this->find(
'first',
array(
'contain' => array(
'UserSession'=>array(
'fields'=>array('user_id', 'session_token')
) ,
'Member' => array(
'fields' => array("*")
)
),
'fields' => array('username', 'email'),
'conditions' => array('User.id' => $id)
));

if (!$row) {
return FALSE;
}
debug($row);exit;
}


and in model Member:

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

$belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'conditions' => '',
'fields' => '',
'order' => ''
),


'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
?>


When I call fuction rest_findUserById() I get this output:

/app/Model/User.php (line 378)

array(
'User' => array(
'username' => 'testuser',
'email' => 'test@gmail.com',
'id' => '71'
),
'Member' => array(
'id' => '11',
'user_id' => '71',
'first_name' => 'Whjc',
'last_name' => 'test_user_lname',
'email' => '',
'phone' => '778899554455',
'image_dir' => '11',
'image' => '92e20fd0260dcc5ea289611221723b6a.jpg',
'address_line_1' => 'Shhd',
'address_line_2' => 'sdf',
'city' => 'Los Angeles Area',
'state' => 'delhi',
'country_id' => '0',
'zip_code' => '56456',
'is_address_different' => false,
'date_of_birth' => '0000-00-00',
'referred_by' => 'asdf',
'created' => '2016-07-27 13:52:30',
'created_by' => '3',
'modified' => '2016-08-02 12:25:22',
'modified_by' => '3',
'status' => false
),
'UserSession' => array(
(int) 0 => array(
'user_id' => '71',
'session_token' => 'a685b3db5ab87a928716c7d8b3272572'
)
)
)


but when I call this code:

$this->Member->recursive = -1;
debug($this->Member->find('first'));


I get this output:

/app/Model/User.php (line 377)

array(
'Member' => array(
'id' => '4',
'user_id' => '64',
'first_name' => 'SDFS SDF',
'last_name' => 'test_user_lname',
'email' => '',
'phone' => '778899554455',
'image_dir' => '',
'image' => '',
'address_line_1' => 'sdf',
'address_line_2' => 'sdf',
'city' => 'Los Angeles Area',
'state' => 'delhi',
'country_id' => '0',
'zip_code' => '56456',
'is_address_different' => false,
'date_of_birth' => '1970-01-01',
'referred_by' => 'asdf',
'created' => '2016-07-22 15:25:30',
'created_by' => '0',
'modified' => '2016-07-22 15:25:30',
'modified_by' => '0',
'status' => false,
'full_name' => 'SDFS SDF test_user_lname'
)
)


as you can see the virtual field i.e.'full_name' is coming in the second output but not in first output.
How can I fix this?

Answer

From the manual

you cannot use virtualFields on associated models

the proposed solution is to copy the virtual field into your model, this way

/app/Model/User.php

$this->virtualFields['member_full_name'] = $this->Member->virtualFields['full_name'];

Of course this does not work for hasMany or HABTM relationships. Also note that in this way you'll find the virtual field in the User data array and not in the Member data array