4

I am using cakephp to run a query, this query consists of custom derived fields as well as some that are in the table.

Cake returns the ones in the table in its own array and the others in an array key of 0 - essentially splitting my results which afterwards I then have to merge together.

I know I can use virtual fields to put the derived fields in to the main array however they are very custom and can change a lot, so it is not suitable to put these fields as virtual fields.

What I'd like is an option of some sort so that cakephp just returns everything in to the 0 key of the array. Something like $this->Model->find('all',$options,RTN_FLAT_ARRAY)

Is something like this already possible?

3
  • Why do you need in single array. Commented Oct 10, 2013 at 9:55
  • Do you want to modify the CakePHP core or you intend to write a plug-in? How would you handle one-to-many relationships? Commented Oct 10, 2013 at 9:55
  • You can use after-find to do that, or just live with (for now) what CakePHP is returning. Is there a reason beyond consistency/convenience you wish to do this? Commented Oct 10, 2013 at 14:06

4 Answers 4

1

This does not make any sense as it would break your result. You're using the "all" find. So it is expected that it will return 0, 1, 2... records in the array not just one record. If you flatten this you get just one record and lose all others.

Use "first" instead and put your custom fields inside the record it will return. You can use the afterFind() callback of the model to modify the result sets.

Also I would not flatten the array, the structure is there for a certain reason. Everything in CakePHP follows conventions. So for example the result will match your form fields when you set them. If you change that structure you'll have to do a lot more manual work in other places. Follow the conventions, they're there for a reason.

Sign up to request clarification or add additional context in comments.

1 Comment

I think you've misread the question. They ask to consolidate the model-name key and the 0-indexed "these fields aren't in a table" key, i.e. $foo[0]['Post']['title'] => $foo[0][0]['title'] which makes perfect sense in various scenarios, though ordinarily it's asked to do it the other way around (consolidate floating data under the main model's key).
1

you can add virtual fields in your controller just before executing find()

$this->Model-virtualFields['field_sum'] = 'SUM(field)';

$this->Model->find('all', array('fields' => array('Model.field_sum')));

in this way virtual fields are attached to the model just for the duration of the action

Comments

1

You may want to look at Hash::flatten
I think the cookbook does a good job of explaining the functio:

http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html

$arr = array(
    array(
        'Post' => array('id' => '1', 'title' => 'First Post'),
        'Author' => array('id' => '1', 'user' => 'Kyle'),
    ),
    array(
        'Post' => array('id' => '2', 'title' => 'Second Post'),
        'Author' => array('id' => '3', 'user' => 'Crystal'),
    ),
);

$res = Hash::flatten($arr);
/* $res now looks like:
   Array (
    [0.Post.id] => 1,
    [0.Post.title] => First Post
    [0.Author.id] => 1,     [0.Author.user] => Kyle
    [1.Post.id] => 2,     [1.Post.title] => Second Post
    [1.Author.id] => 3,    [1.Author.user] => Crystal

The "sister" function is Hash::expand - which restores the array to its preflattend state.

Of course you could always write a loop to present the array in whatever format you like, but thats not very "cakeish"

Comments

0

For cakephp 2 You may want to look at Set::flatten

https://book.cakephp.org/2/en/core-utility-libraries/set.html#Set::flatten

$arr = array(
    array(
        'Post' => array('id' => '1', 'title' => 'First Post'),
        'Author' => array('id' => '1', 'user' => 'Kyle'),
    ),
    array(
        'Post' => array('id' => '2', 'title' => 'Second Post'),
        'Author' => array('id' => '3', 'user' => 'Crystal'),
    ),
);
$res = Set::flatten($arr);
/* $res now looks like:
    Array (
        [0.Post.id] => 1
        [0.Post.title] => First Post
        [0.Author.id] => 1
        [0.Author.user] => Kyle
        [1.Post.id] => 2
        [1.Post.title] => Second Post
        [1.Author.id] => 3
        [1.Author.user] => Crystal
    )
*/

and also you can look at Set::classicExtract

https://book.cakephp.org/2/en/core-utility-libraries/set.html#Set::classicExtract

$users = $this->User->find('all');
$results = Set::classicExtract($users, '{n}.User');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.