有没有办法将嵌套集合中的对象计数作为 laravel 中的属性附加?

Is there a way to append a count of objects in a nested collection as an attribute in laravel?

我是 Laravel 的新手,特别是 eloquent。我有一个比赛模型,这场比赛有进球

class Match extends Model
{
    use HasFactory;

    public function goals()
    {
        return $this->hasMany(Goal::class, 'match');
    }

}

我是这样从 Controller 调用它的:

public function matchesWithGoals()
    {
        $matches = Match::with('goals')->get();
        return compact('matches');
    }

这将返回每场比赛及其自己的目标集合。目前一切顺利。

{
"matches": [
{
"id": 13,
"date": "2022-01-05",
"goals": [
   {
      "id": 2,
      "player": 4,
      "match": 13,
      "team": "b"
   },
   {
      "id": 3,
      "player": 13,
      "match": 13,
      "team": "b"
   },
   {
      "id": 4,
      "player": 4,
      "match": 13,
      "team": "a"
   }]
}]}

我想做的是获取每个嵌套的目标集合,根据团队相加,并附加自定义属性“goalsTeamA”、“goalsTeamB”、“matchResult”。

我试着分开做这件事,比如,获得所有比赛,获得所有进球,然后加入他们。但似乎应该有一种直接的方法来计算基于属性的嵌套集合中的元素,在本例中为团队,并附加属性,因此预期的结果将是这样的:

{
"matches": [
   {
      "id": 13,
      "date": "2022-01-05"
      "goalsTeamA": 1,
      "goalsTeamB": 2,
      "Result": "b"
   }, 
   {
      "id": 14,
      "date": "2022-01-12"
      "goalsTeamA": 3,
      "goalsTeamB": 7,
      "Result": "b"
   }]
}

我怎样才能做到这一点?

顺便说一句,我尝试这样做而不是将此列与分数一起添加到数据库中的原因是因为我不只是显示分数计数。比赛还有其他关系,比如花名册,我的目标是学习如何处理这些嵌套关系集合并将这些结果作为属性附加。总结 golas 似乎是最基本的场景。

有几种方法可以做到这一点,因此我将提供一种可能的解决方案。

您可以查看 Laravel 访问器 - https://laravel.com/docs/8.x/eloquent-mutators#defining-an-accessor

在您的情况下,您可以在 Match 模型上使用如下函数:

public function getGoalsTeamAAttribute() {
    // calculate and return goal count for team A
}

public function getGoalsTeamBAttribute() {
    // calculate and return goal count for team B
}

public function getResultAttribute() {
    // calculate and return result
}

然后您可以执行以下两项操作之一以将此数据包含在集合中。

  1. $appends = ['result', 'goals_team_a', 'goals_team_b']; 添加到匹配模型的顶部。当您将其转换为数组或 JSON 时,这会将这些值附加到集合中。 Google 'laravel appends' 了解更多信息。

  2. 当您将匹配作为 eloquent 对象时,只需调用 $match->goals_team_a 即可即时进行计算。您需要注意这种方法的 n+1 个问题,因为它会 运行 您的 getGoalsTeamAAttribute 函数中的任何数据库查询。您需要确保在 运行 宁 $match->goals_team_a.

    之前延迟加载 (->with('goals'))