Reputation: 653
I see data returned in different formats for different models and I don't know why.
I have the following 2 models defined (I realize the associations don't make complete sense - I changed their context - but the issue exists :) :
//
// RecipeItem Model
//
class RecipeItem extends AppModel
public $belongsTo = array(
'Recipe' => array(
'className' => 'Recipe',
'foreignKey' => 'recipe_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Ingredient' => array(
'className' => 'Ingredient',
'foreignKey' => 'ingredient_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
};
//
// Ingredient Model
//
class Ingredient extends AppModel {
public $belongsTo = array(
'IngredientType' => array(
'className' => 'IngredientType',
'foreignKey' => 'ingredient_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
};
//
// IngredientType
//
class IngredientType extends AppModel {
public $hasMany = array(
'Ingredient' => array(
'className' => 'Ingredient',
'foreignKey' => 'ingredient_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
};
I get my data returned in this format :
"RecipeItem": [
{
"id": "16181",
"recipe_id": "4150",
"ingredient_id": "6866",
"amount_in_ounces": "16.00",
"created": "2014-08-06 21:34:50",
"modified": "2014-08-06 21:34:50",
"Ingredient": {
"id": "6866",
"ingredient_type_id": "2",
"user_id": "1",
"name": "Cinnamon",
"notes": "Cinnamon spice notes",
"favorite": "0",
"created": "2014-07-20 23:13:08",
"modified": "2014-07-20 23:13:08",
"IngredientType": {
"id": "2",
"name": "Spice"
}
}
},
];
when I use Containable in my Controller :
$data = $this->Recipe->find( 'first',
array(
'contain' => array(
'RecipeItem' => array('Ingredient' => array('IngredientType')),
),
'conditions' => array(
'Recipe.id' => $this->request['id'],
'Recipe.user_id' => $this->request['user_id']
)
)
);
But CakePHP returns the default format at times :
{
"Ingredient": {
"id": "6784",
"ingredient_type_id": "5",
"user_id": "1",
"name": "Cinnamon",
"notes": "Some notes...",
"favorite": "0",
"created": "2014-07-20 23:13:08",
"modified": "2014-07-20 23:13:08"
},
"IngredientType": {
"id": "5",
"name": "Allspice"
},
"User": {
"id": "1",
"username": "ccampise",
"password": "3eccc6ad7b84c40434740c782266ec3cced19133",
"notes": null,
"created": "2014-05-16 18:27:56",
"modified": "0000-00-00 00:00:00"
}
},
....
at other times when I use the same Containable notation :
$data = $this->Ingredient->find( 'first',
array(
'contain' => array('IngredientType'),
)
);
I'm not sure I have a preference, but I do prefer to use one or the other, and not both for consistency in my models.
Any thoughts? Thanks!
Upvotes: 1
Views: 60
Reputation: 761
I was having the same issue. This function will consistently nest data returned by cake's inconsistent contain results.
// model
public function formatData(&$data)
{
if (isset($data[0])) {
foreach ($data as $key => $item) {
$this->formatData($data[$key]);
}
} else {
$firstKey = key($data);
$mainData = reset($data);
unset($data[key($data)]);
$data = array($firstKey => array_merge($mainData, $data));
}
}
// controller
$this->User->formatData($data);
As a side note CakePHP 3 does not seem to suffer from this inadequacy.
Upvotes: 0
Reputation: 1069
This is CakePHP's default behavior, determining on how to place 1-n relations in the result array based on the model you're querying.
If you really want to change this, you can always hook into the afterFind()
, but it will cause more confusion in the future.
I'm afraid you'll have to get used to this.
Upvotes: 0