简体   繁体   English

Laravel-有一个或多个其他关系的口才关系

[英]Laravel - Eloquent relation whereHas one or more other relations

I'm learning Laravel and Laravel eloquent at the moment and now I try to solve a problem using relations in Laravel. 我现在正在雄辩地学习Laravel和Laravel,现在我尝试使用Laravel中的关系解决问题。 This is what I want to archive: 这是我要存档的内容:

The database holds many sport clubs. 该数据库包含许多体育俱乐部。 A sport club has a lot of teams. 一个体育俱乐部有很多球队。 Each team has games. 每个团队都有比赛。 The teams table has a column named club_id . teams表有一个名为club_id的列。 Now I want to create Eloquent relations to get all games of a club. 现在,我想创建雄辩的关系以获取俱乐部的所有比赛。

Here is what I got so far: 这是到目前为止我得到的:

Club model 俱乐部模型

id => PRIMARY

public function games()
    {
        return $this->hasMany('App\Models\Games')->whereHas('homeTeam')->orWhereHas('guestTeam');
    }

Game model 游戏模型

home_id => FOREIGN KEY of team ; guest_id => FOREIGN KEY of team

public function homeTeam()
    {
        return $this->belongsTo('App\Models\Team','home_id')->where('club_id','=', $club_id);
    }

    public function guestTeam()
    {
        return $this->belongsTo('App\Models\Team','guest_id')->where('club_id','=', $club_id);
    }

Team model 团队模式

id => PRIMARY ; club_id => FOREIGN

In my controller all I want to do is Club::findOrFail($id)->games() 在我的控制器中,我要做的就是Club::findOrFail($id)->games()

Executing the code above returns a SQL error that the games table does not have a column named club_id . 执行上面的代码将返回一个SQL错误,即游戏表没有名为club_id的列。

What is the correct way to create this kind of relation? 建立这种关系的正确方法是什么?

Thanks! 谢谢!

EDIT 编辑

Thanks to Nikola Gavric I've found a way to get all Games - but only where club teams are the home or away team. 多亏了尼古拉·加夫里克(Nikola Gavric),我找到了一种获得所有比赛的方式-但仅在俱乐部队是主队或客队的情况下。

Here is the relation: 关系如下:

public function games()
    {
        return $this->hasManyThrough('App\Models\Game','App\Models\Team','club_id','home_id');
    }

How is it possible to get the games where the home_id OR the guest_id matches a team of the club? 如何获得home_id或guest_id与俱乐部球队匹配的比赛? The last parameter in this function does not allow an array. 此函数中的最后一个参数不允许使用数组。

There is method to retrieve a "distant relationship with an intermediary" and it is called Has Many Through . 有一种方法可以检索“与中介之间的远距离关系”,它被称为“ 具有很多通过”

There is also a concrete example on how to use it which includes Post , Country and User , but I think it will be sufficient to give you a hint on how to create games relationship inside of a Club model. 还有一个有关如何使用它的具体示例,其中包括PostCountryUser ,但我认为这足以为您提供有关如何在Club模型内部创建games关系的提示。 Here is a link, but when you open it, search for hasManyThrough keyword and you will see an example. 是一个链接,但是当您打开它时,搜索hasManyThrough关键字,您将看到一个示例。

PS: With right keys naming you could achieve it with: PS:使用正确的keys naming您可以使用以下方法实现此目的:

public function games()
{
    return $this->hasManyThrough('App\Models\Games', 'App\Models\Teams');
}

EDIT #01 编辑#01

Since you have 2 types of teams, you can create 2 different relationships where each relationship will get you one of the type you need. 由于您有2种类型的团队,因此您可以创建2种不同的关系,每种关系都会使您成为所需的一种类型。 Like this: 像这样:

public function gamesAsHome()
{
    return $this
        ->hasManyThrough('App\Models\Games', 'App\Models\Teams', 'club_id', 'home_id');
}

public function gamesAsGuests()
{
    return $this
        ->hasManyThrough('App\Models\Games', 'App\Models\Teams', 'club_id', 'guest_id');
}

EDIT #02 编辑#02

Merging Relationships : To merge these 2 relationships, you can use merge() method on the Collection instance, what it will do is, it will append all the records from second collection into the first one . 合并关系 :要合并这两个关系,可以在Collection实例上使用merge()方法,它将执行的操作是,它将第二个集合中的所有记录追加到第一个 集合中

$gamesHome = $model->gamesAsHome;
$gamesGuests = $model->gamesAsGuests;
$games = $gamesHome->merge($gamesGuests);

return $games->unique()->all();

Thanks to @HCK for pointing out that you might have duplicates after the merge and that unique() is required to get the unique games after the merge . 感谢@HCK指出合并后您可能会重复,并且在合并后需要unique()才能获得唯一游戏


EDIT #03 编辑#03

sortBy also offers a callable instead of a attribute name in cases where Collection contains numerical indexing . Collection包含numerical indexing情况下, sortBy还提供了callable而不是attribute name You can sort your Collection like this: 您可以像这样对您的Collection进行排序:

$merged->sortBy(function($game, $key) {
    return $game->created_at;
});

When you define that Club hasMany games you are indicating that game has a foreign key called club_id pointing to Club. 当您定义Club hasMany游戏时,表示该游戏具有指向Club的名为club_id的外键。 belongsTo is the same but in the other way. belongsTo是相同的,但belongsTo These need to be coherent with what you have on your database, that means that you need to have defined those keys as foreign keys on your tables. 这些需要与数据库上的内容保持一致,这意味着您需要将这些键定义为表上的外键。

Try this... 尝试这个...

Club model 俱乐部模型

public function games()
    {
        return $this->hasMany('App\Models\Games');
    }

Game model 游戏模型

public function homeTeam()
    {
        return $this->belongsTo('App\Models\Team','home_id');
    }

    public function guestTeam()
    {
        return $this->belongsTo('App\Models\Team','guest_id');
    }

Your Query like 您的查询像

Club::where('id',$id)->has('games.guestTeam')->get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM