【问题标题】:Laravel Multiple linking column in another table with relationships?Laravel 在另一个具有关系的表中的多个链接列?
【发布时间】:2023-03-11 09:46:01
【问题描述】:

我正在尝试在 Laravel 中创建一个排行榜,但我又遇到了一些问题,猜测是什么,关系。他们似乎从未在 Laravel 中为我工作。好像他们讨厌我一样。

我有一个匹配模式

<?php

namespace App\Database;

use Illuminate\Database\Eloquent\Model;

class Match extends Model
{
    protected $primaryKey = 'id';

    protected $table = 'matches';
    public $timestamps = false;
    protected $guarded = ['id'];
}

还有一个用于团队的模态,但带有 match() 函数

<?php

namespace App\Database;

use Illuminate\Database\Eloquent\Model;

class Team extends Model
{
    protected $primaryKey = 'id';

    protected $table = 'teams';
    public $timestamps = false;
    protected $guarded = ['id'];

    public function matches() {
        return $this->hasMany('App\Database\Match', 'team_one_id, team_two_id');
    }
}

我认为问题与team_one_id, team_two_id 有关,因为团队的主键可能位于另一个表的任一列中。在matches() 上调用count() 时会引发错误。

SQLSTATE[42S22]: 未找到列:1054 未知列 'matches.team_one_id, team_two_id' in 'where 子句' (SQL: select count(*) as aggregate from matches where matches.team_one_id, team_two_id = 1 和matches.team_one_id, team_two_id 不为空)

【问题讨论】:

  • 看看$this-&gt;hasMany中的第二个参数
  • 能否提供比赛和球队的表格结构。

标签: php laravel


【解决方案1】:

你能试试这个语法吗

return $this->hasMany('modelPath', 'foreign_key', 'local_key');

【讨论】:

  • 这是一个糟糕的答案。你所做的只是复制+粘贴 Laravel 文档。这没有显示如何做多个键
【解决方案2】:

匹配表是否有一个名为“team_id”的列? 因为它是 laravel 文档中用于映射表的默认命名约定。

如果您确实有该列并填充数据,您可以从 match() 关系中删除外键和本地键。你不需要它。 Laravel 会自动为你映射。

如果您在 Matches 表中没有“team_id”,请添加该列并为比赛添加相应的团队 ID。

<?php

namespace App\Database;

use Illuminate\Database\Eloquent\Model;

class Team extends Model
{
    protected $primaryKey = 'id';

    protected $table = 'teams';
    public $timestamps = false;
    protected $guarded = ['id'];

    public function matches() {
        return $this->hasMany('App\Database\Match');
    }
}

【讨论】:

  • 你的回答毫无意义。一场比赛怎么能只有 2 支球队的 1 列?
【解决方案3】:

这样就可以实现了,在Team Model中添加这些关系和方法

 public function homeMatches() {
    return $this->hasMany('App\Database\Match', 'team_one_id');
 }

 public function awayMatches() {
    return $this->hasMany('App\Database\Match', 'team_two_id');
 }

 public function matches() {
    return $this->homeMatches->merge($this->awayMatches);
 }

现在获取数据

$team = Team::find(1);
$matches = $team->matches(); //now it will fetch all matches for both columns

如果您想获取匹配项作为属性,那么您可以添加一种方法 在您的团队模型中

public function getMatchesAttribute()
{
   return $this->homeMatches->merge($this->awayMatches);
}

现在您可以使用$matches = $team-&gt;matches; 获取匹配项

这就是区别

$team-&gt;matches 返回Illuminate\Database\Eloquent\Collection

$team-&gt;matches() 返回Illuminate\Database\Eloquent\Relations\{Relation Name}

您不能像 Team::with('matches') 这样在 Eager loading 中使用 matches,因为 matches 不是关系并且会导致您的错误。您可以做的是在急切加载中添加homeMatchesawayMatches,然后调用$team-&gt;matches()

$teams = Team::with('homeMatches', 'awayMatches')->get(); 
$teams->each(function ($team) {
    print_r($team);
    print_r($team->matches()); 
});

【讨论】:

  • 不,如果您阅读我的问题,您会注意到我需要将列设为 team_one_idteam_two_id,您的回答基本上会破坏我的代码。
  • 你好。感谢您更新您的答案。您的更新导致错误。 Method Illuminate\Database\Eloquent\Collection::addEagerConstraints does not exist.
  • @wilino 你试过$matches = $team-&gt;matches(); 而不是$matches = $team-&gt;matches;
  • @walino 我已经测试了代码并且运行良好
  • @walino 我已经用描述更新了我的答案,希望这次对你有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 2020-10-08
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 2020-01-15
相关资源
最近更新 更多