Reputation: 2154
So afterFind works fine and dandy when I'm within the corresponding model/controller. However, when calling an associated model, the data sent to the afterFind callback is formatted differently. This causes afterFind to crap out because it can't find the same array indexes it did when just working within the original model/controller.
Anyone know why, or what a fix might be?
Upvotes: 3
Views: 2596
Reputation: 1218
It appears that Cake 2.6 includes a fix for this, ensuring that all $results
arrays are consistently formatted. I've done a little testing with the RC release and it does seem to work, with arrays all being passed in the format {n}.ModelName.data
.
The fix is enabled by default, but you can also revert to the legacy behaviour if need be. Just add the following to your model (or AppModel) definition:
public $useConsistentAfterFind = false;
Upvotes: 1
Reputation: 3474
$primary
may not be very helpful; I've found that it is always false
when using ContainableBehaviour beyond the first depth:
$this->Model->find('first', array(
'contain' => array(
'SecondaryModel' => array(
'TertiaryModel',
),
),
));
If you're setting a value based on a related model, you can check for its presence to deal with either structure like this:
function afterFind($results, $primary) {
if (isset($results['TertiaryModel'])) {
$results['secondary_model_field'] = 'value';
}
else {
foreach ($results as &$result) {
if (is_array($result) && isset($result['TertiaryModel'])) {
$result[$this->alias]['secondary_model_field'] = 'value';
}
} unset($result);
}
return $results;
}
Alternately you may be able to just check for the location of a field on the model itself. If the field doesn't exist at the top level, you will need to iterate over the set of results.
Upvotes: 3
Reputation: 6767
This is what the second parameter to afterFind
callback is for.
$primary
tells if you if the find was called from this model directly (true), or if it was called by an associated model (false).
A note from the book:
The $primary parameter indicates whether or not the current model was the model that the query originated on or whether or not this model was queried as an association. If a model is queried as an association the format of $results can differ;
Code expecting $primary to be true will probably get a "Cannot use string offset as an array" fatal error from PHP if a recursive find is used.
So you may need different processing logic depending on the value of $primary
Upvotes: 2