Coming Soon

1 minute read

Test post with some syntax highlighting and stuff.

I just stumbled on a bug in CakePHP that prevents related child records from being returned when only selecting a single field from the parent. It looks something like this:

<?php
$this->Model->find('all', array(
  'contain' => array(
    'Parent' => array(
      'fields' => array('id', 'type'),
      'Child' => array(
        'fields' => array('id', 'type')
      )
    )
  )
);
// Returns as expected
//array(
//  'Model' => array(...),
//  'Parent' => array(
//    'id' => '',
//    'type' => '',
//    'Child' => array(
//      array(
//        'id' => '',
//        'type' => ''
//      ),
//      ...
//    )
//  )
//)

Now if we modify the contain for Parent to return only one field we lose all Child records:

<?php
$this->Model->find('all', array(
  'contain' => array(
    'Parent' => array(
      'fields' => array('id'),
      'Child' => array(
        'fields' => array('id', 'type')
      )
    )
  )
);
// Returns no Child records
//array(
//  'Model' => array(...),
//  'Parent' => array(
//    'id' => '',
//    'type' => '',
//  )
//)

This is due to a bug in Model/DataSource/DboSource.php:

<?php
//...
if (count($merge[0][$association]) > 1) {
    foreach ($merge[0] as $assoc => $data2) {
//...

Since Parent only has one field, id, it does not do the merge. This has been corrected in CakePHP 2.4.2 to !empty() instead of count() > 1.

This has been fixed in the CakePHP master branch with this commit.

Tags:

Updated: