Eloquent:从 `hasMany` -> `hasOne` 关系中获取 'max' 值

Eloquent: Get 'max' values from a `hasMany` -> `hasOne` relationship

我有一个有趣的 eloquent 挑战,我的知识还不足以解决这个问题,希望聪明的人能给我一些指导。我读过这个:Getting just the latest value on a joined table with Eloquent,它非常接近我想要的,但我在那里有一个额外的 table 级别。 我有两个这样的 table:

User有很多Assessment。每个 Assessment hasOne body_fat_testing(以及我还需要使用的其他 4 个 hasOne)。

每个 body_fat_testing table 都有几列我感兴趣(见下文)。 我想从每个用户 "grandchild" 获得 "best" 结果。

所以在所有评估中,最好的 lean_massbody_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');
}

我想要 "best" 的总值大约有 30 个。关于如何在不单独遍历每个值的情况下完成此操作的任何想法?

assessment table:

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

body_fat_testing table:


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

试试这个方法(假设您有三个表的模型并且它们之间存在关系):

首先,您将 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()

从那里我认为你可以适应你的其他 "has ones"。

你也可以这样做:

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

不确定我更喜欢哪种方式。前者更容易理解,但创建的方法更多。这个比较难理解但是方法比较少