Dynamically add virtual field in cakephp

半世苍凉 提交于 2020-01-01 22:06:42

问题


I am using CakePHP 2.1.3; I want to create a virtual field dynamically in a controller. Is it possible? The problem is when I am trying to find max value in a table it gives me another array from the model array. Please ask if you need more information.

When I am trying to execute the following query,

$find_max_case_count = $this->CaseMaster->find('first', array(
    'conditions' => array(
        'CaseMaster.CLIENT_ID' => $client_id,
        'CaseMaster.CASE_NO LIKE' => '%-%'
    ),
    'fields' => array('max(CaseMaster.CASE_NO) AS MAX_NO')
));

It is giving me an array like:

[0]=> array([MAX_NO]=> 52)

However I want it to be like as:

[CaseMaster] => array([MAX_NO] => 52)

回答1:


I found a solution. I can make the virtual field at runtime. The code should looks like:

$this->CaseMaster->virtualFields['MAX_NO'] = 0;

Write it just above the find query and the query will remain same as it was written. This link was helpful to find out the solution.




回答2:


There is no way (as far as I am knowledgeable) to create virtual fields "on the fly". What virtual fields are is "arbitrary SQL expressions" that will be executed when a find runs through the Model and "will be indexed under the Model's key alongside other Model fields".

What do you need to do with "dynamically created virtual fields"? If you explain what exactly you need to accomplish maybe we can provide a different (even more suitable? :) ) solution? I'd personally be happy to help you.

After you editing your question I can say that what you're getting is the way the array should be returned, this is because of the fields parameter. If you want to get a different structure out of it I suggest applying a callback to format it. Firstly move the method inside the CaseMaster Model:

public function getMaxCaseCount($client_id){
$data = $this->find('first', array(
                   'conditions' => array(
                                   'CaseMaster.CLIENT_ID' => $client_id,  
                                   'CaseMaster.CASE_NO LIKE' => '%-%'),
                   'fields' => array('max(CaseMaster.CASE_NO) AS MAX_NO')));
return array_map(array('CaseMaster', '__filterMaxCaseCount'), $data);
}

private function __filterMaxCaseCount($input){
    //This is just an example formatting
    //You can do whatever you would like here.
    $output['CaseMaster'] = $input[0];
    return $output;
}

The array_map function will apply the __filterMaxCaseCount callback method so that when you call:

$this->CaseMaster->getMaxCaseCount($client_id);

from your controller you will get the data in the way you need it. The array_map function could also look like this:

return array_map(array($this, '__filterMaxCaseCount'), $data);

because you're in the same Class.




回答3:


Just adding your model alias to field definition also works for this purpose

'fields' => array('max(CaseMaster.CASE_NO) AS CaseMaster__MAX_NO')


来源:https://stackoverflow.com/questions/11305111/dynamically-add-virtual-field-in-cakephp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!