雄辩的:从“ hasMany”->“ hasOne”关系中获取“ max”值

时间:2019-11-08 16:03:59

标签: php laravel eloquent eloquent--relationship

我面临着一个有趣的雄辩挑战,我的知识还不足以解决它,希望您聪明的人可以给我一些指导。我读过这篇文章:Getting just the latest value on a joined table with Eloquent,它非常接近我想要的内容,但是我在那里有一个更高级别的表。 我有两个这样的表:

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

每个body_fat_testing表中都有我感兴趣的几列(见下文)。 我想从每个用户的每个“孙子”中获得“最佳”结果。

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

大约有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 个答案:

答案 0 :(得分:1)

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

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

我认为您可以从那里适应其他“有”的人。

答案 1 :(得分:0)

您也可以这样:

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

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