Despite the fact that using a VARCHAR(255)
as a foreign key is probably highly inefficient and/or will require huge indices, I guess that generally an option that defines the foreign key of the other table would come in handy here, similar to targetForeignKey
for belongsToMany
associations. You may to want to suggest that as an enhancement.
Result formatters
Currently this doesn't seem to be possible out of the box using associations, so you'd probably have to select and inject the associated records yourself, for example in a result formatter.
$Villas
->find()
->formatResults(function($results) {
/* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\Collection */
// extract the custom foreign keys from the results
$keys = array_unique($results->extract('complex')->toArray());
// find the associated rows using the extracted foreign keys
$villas = \Cake\ORM\TableRegistry::get('Villas')
->find()
->where(['complex IN' => $keys])
->all();
// inject the associated records into the results
return $results->map(function ($row) use ($villas) {
if (isset($row['complex'])) {
// filters the associated records based on the custom foreign keys
// and adds them to a property on the row/entity
$row['complexs'] = $villas->filter(function ($value, $key) use ($row) {
return
$value['complex'] === $row['complex'] &&
$value['id'] !== $row['id'];
})
->toArray(false);
}
return $row;
});
});
This would fetch the associated rows afterwards using the custom foreign keys, and inject the results, so that you'd end up with the associated records on the entities.
See also Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields
There might be other options, like for example using a custom eager loader that collects the necessary keys, combined with a custom association class that uses the proper key for stitching the results together, see