When a cross-ref table has composite FKs, Propel doesn't properly handle xref deletion in doSave methods.
Example
document {
id
pk (id)
}
account {
user_id
organisation_id
pk (user_id, organisation_id)
fk (user_id) - > user(id)
fk (organisation_id) -> organisation(id)
}
document_access_xref {
user_id
tenant_id
document_id
pk (user_id, organisation_id, document_id)
fk (user_id, organisation_id) -> account(user_id, organisation_id)
fk (document_id) -> document(id)
}
Propel then generates this code
if ($this->permittedDocumentsScheduledForDeletion !== null) {
if (! $this->permittedDocumentsScheduledForDeletion->isEmpty()) {
$pks = [];
$pk = $this->getPrimaryKey();
foreach ($this->permittedDocumentsScheduledForDeletion->getPrimaryKeys(false) as $remotePk) {
$pks[] = [$pk, $remotePk];
}
DocumentAccessXrefQuery::create()
->filterByPrimaryKeys($pks)
->delete($con);
$this->permittedDocumentsScheduledForDeletion = null;
}
}
The problem is that filterByPrimaryKeys() expects a flat array of values, while the above code appends composite PK as a nested array ([$pk, $remotePk], where $pk is an array).
Workaround
As temporary possible workaround can be to override filterByPrimaryKeys() in the specific model query class to add an extra normalization pass:
public function filterByPrimaryKeys($keys)
{
$keys = Arrays::map($keys, function (array $key) {
if (array_filter($key, 'is_array')) {
return array_merge(
...array_map(fn ($component) => (array) $component, $key),
) ;
}
return $key;
});
return parent::filterByPrimaryKeys($keys);
}
When a cross-ref table has composite FKs, Propel doesn't properly handle xref deletion in doSave methods.
Example
Propel then generates this code
The problem is that
filterByPrimaryKeys()expects a flat array of values, while the above code appends composite PK as a nested array ([$pk, $remotePk], where$pkis an array).Workaround
As temporary possible workaround can be to override
filterByPrimaryKeys()in the specific model query class to add an extra normalization pass: