implement multi relation loading #25

Merged
bence merged 1 commits from feature/multiple-relations into master 2023-06-17 14:32:56 +02:00
3 changed files with 43 additions and 0 deletions
Showing only changes of commit fc4c3234a7 - Show all commits

View File

@ -16,6 +16,8 @@ interface IPersistentDataManager
public function loadRelationsFromDb(Model $model, bool $recursive = false, array $withRelations = []): void; public function loadRelationsFromDb(Model $model, bool $recursive = false, array $withRelations = []): void;
public function loadMultiRelationsFromDb(array $models, string $relation, bool $useRelations = false, array $withRelations = []): void;
public function saveToDb(Model $model): void; public function saveToDb(Model $model): void;
public function deleteFromDb(Model $model): void; public function deleteFromDb(Model $model): void;

View File

@ -8,6 +8,8 @@ abstract class Model
protected static array $relations = []; protected static array $relations = [];
protected static array $multiRelations = [];
protected $id = null; protected $id = null;
private array $snapshot = []; private array $snapshot = [];
@ -27,6 +29,11 @@ abstract class Model
return static::$relations; return static::$relations;
} }
public static function getMultiRelations(): array
{
return static::$multiRelations;
}
public function setId($id): void public function setId($id): void
{ {
$this->id = $id; $this->id = $id;

View File

@ -92,6 +92,40 @@ class PersistentDataManager implements IPersistentDataManager
} }
} }
public function loadMultiRelationsFromDb(array $models, string $relation, bool $useRelations = false, array $withRelations = []): void
{
if (count($models) === 0) {
return;
}
$parentModelType = get_class($models[0]);
$relationModelsSetter = 'set' . str_replace('_', '', ucwords($relation, '_'));
[$relationModelType, $reverseRelation] = call_user_func([$parentModelType, 'getMultiRelations'])[$relation];
$reverseRelationIdGetter = 'get' . str_replace('_', '', ucwords($reverseRelation, '_')) . 'Id';
$parentModelsById = [];
foreach ($models as $model) {
$parentModelsById[$model->getId()] = $model;
}
$select = new Select($this->dbConnection);
$select->where($reverseRelation . '_id', 'IN', array_keys($parentModelsById));
$relationsByParentModelId = [];
foreach ($this->selectMultipleFromDb($select, $relationModelType, $useRelations, $withRelations) as $relationModel) {
$reverseRelationId = $relationModel->$reverseRelationIdGetter();
if (!isset($relationsByParentModelId[$reverseRelationId])) {
$relationsByParentModelId[$reverseRelationId] = [];
}
$relationsByParentModelId[$reverseRelationId][] = $relationModel;
}
foreach ($parentModelsById as $parentModelId => $parentModel) {
$relationModels = $relationsByParentModelId[$parentModelId] ?? [];
$parentModel->$relationModelsSetter($relationModels);
}
}
public function saveToDb(Model $model): void public function saveToDb(Model $model): void
{ {
$this->syncRelations($model); $this->syncRelations($model);