Eloquent: получить значения 'max' из отношения `hasMany` ->` hasOne` - PullRequest
1 голос
/ 08 ноября 2019

У меня есть интересное красноречивое задание, и мои знания еще не достаточно, чтобы справиться с ним, надеясь, что вы, умные люди, сможете дать мне некоторое руководство. Я прочитал это: Получение только последнего значения в объединенной таблице с Eloquent , и оно очень близко к тому, что я хочу, но у меня есть дополнительный уровень таблиц там. У меня есть две таблицы, подобные этой:

User s имеют много Assessment s. Каждая Assessment hasOne body_fat_testing (и еще 4 hasOne s, которые мне также нужно использовать).

Каждая таблица body_fat_testing имеет несколько интересующих меня столбцов (см. Ниже) вЯ хотел бы получить «лучший» результат от каждого «внука» для каждого пользователя.

Так что из всех оценок лучший lean_mass, body_fat_percentage и т. Д. У меня есть это до сих пор:

$users = User::with(
    [
        'trainer',
        'firstAssessment.body_fat_testing',
        'firstAssessment.circumference_measurement',
        'firstAssessment.exercise_testing',
        'firstAssessment.overhead_squat_movement_screen',
        'firstAssessment.push_ups_movement_screen',
        'lastAssessment.body_fat_testing',
        'lastAssessment.circumference_measurement',
        'lastAssessment.exercise_testing',
        'lastAssessment.overhead_squat_movement_screen',
        'lastAssessment.push_ups_movement_screen',
    ]
)->find($request->input('user_ids'));
...
(in User.php)

public function lastAssessment()
{
    return $this->hasOne('App\Assessment')->latest('assessment_date');
}

public function firstAssessment()
{
    return $this->hasOne('App\Assessment')->orderBy('assessment_date');
}

Всего около 30 значений, из которых я хочу получить «лучшее». Любые идеи о том, как сделать это, не просматривая все значения в отдельности?

assessment таблица:

+----+---------+-----+--------+---------------+
| id | user_id | age | weight | assessed_date |
+----+---------+-----+--------+---------------+
|  1 |       7 |  24 |    204 | 2019-10-29    |
+----+---------+-----+--------+---------------+

body_fat_testing таблица:


+----+---------------+-----------+---------------------+
| id | assessment_id | lean_mass | body_fat_percentage |
+----+---------------+-----------+---------------------+
|  1 |             1 |    130.97 |               21.10 |
+----+---------------+-----------+---------------------+

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Попробуйте этот подход (предполагается, что у вас есть модели для трех таблиц и существуют связи между ними):

Сначала вы свяжете свою модель User с моделью BodyFatTesting,:

public function bodyFatTestings() {
    return $this->hasManyThrough("App\BodyFatTesting", "App\Assessment");
}

Затем вы создадите вторичный метод bestBodyFatPercentage, например:

public function bestBodyFatTesting() {
    return $this->bodyFatTestings()->max('body_fat_testing.body_fat_percentage');
}

Чтобы использовать его, просто получите модель в зависимости от того, что вы предпочитаете, и позвоните bestBodyFatTesting().

Оттуда, я думаю, вы можете адаптировать его к своим другим "имеет".

0 голосов
/ 08 ноября 2019

Вы также можете сделать это следующим образом:

    public function bestLeanMass()
    {
        return $this->hasOneThrough('App\BodyFatTesting', 'App\Assessment')
            ->selectRaw('user_id, max(lean_mass) as aggregate')
            ->groupBy('user_id');
    }

Не уверен, какой путь мне нравится больше. Первое немного легче понять, но создает больше методов. Этот сложнее понять, но методов меньше.

...