У вас есть следующие опции:
Манипулировать массивами
Получить массив пользователей, получить массив проектов, объединить их в цикл, вернуть данные обратно.Это определенно будет иметь производительность, используя больше памяти.Обратите внимание, что эта реализация представляет печально известную проблему N + 1, то есть вы вводите запрос в цикле, загружая базу данных больше, чем требуется.
$data = [];
$users = Users::find(
[
'columns' => 'id, first_name, last_name, login'
]
);
foreach ($users as $user) {
$record = $user->toArray();
$projects = Projects::find(
[
'conditions' => 'user_id = :user_id:',
'bind' => [
'user_id' => $user->id,
]
]
);
// now add the projects to the record
$record['projects'] = $projects->toArray();
// Add the record to the final array
$data[] = $record;
}
Использование отношений
Проще работать, новсе еще страдает от проблемы N + 1
$data = [];
$users = Users::find(
[
'columns' => 'id, first_name, last_name, login'
]
);
foreach ($users as $user) {
$record = $user->toArray();
$projects = $user->getRelated('projects');
// now add the projects to the record
$record['projects'] = $projects->toArray();
// Add the record to the final array
$data[] = $record;
}
Использование компоновщика
Я понимаю, что вы упомянули, что вы не хотите использовать компоновщик, но подумайте об этом, поскольку он предлагает лучшеепроизводительность для ваших нужд
$results = (new Builder())
->addFrom(Users::class, 'u')
->leftJoin(Projects::class, 'p')
->columns(
[
'u_id' => 'u.id',
'first_name' => 'u.first_name',
'last_name' => 'u.last_name',
'login' => 'u.login',
'p_id' => 'p.id,
'p_name' => 'p_name',
'p_desc' => 'p_desc',
]
)
->orderBy('u.last_name, u.first_name, p.p_name')
->getQuery()
->execute()
;
$data = array();
foreach ($results as $record) {
$data[$results->u_id] = [
'id' => $record->id,
'first_name' => $record->first_name,
'last_name' => $record->last_name,
'login' => $record->login,
'projects'[$result->p_id] => [
'id' => $result->p_id,
'p_name' => $result->p_name,
'p_desc' => $result->p_desc,
],
];
}
return $data;
Примечание Приведенный выше код приведен для демонстрации, я не проверял его, поэтому вы можете настроить его в соответствии с вашими потребностями