Laravel中的三个表如何在Eloquent模型中定义一对多和多对多关系?

How to define one-to-many together with many-to-many relation in Eloquent model for three tables in Laravel?

我有三个表:

关系是:

查看简化模型:

我需要显示项目的所有补丁。我可以这样做:

@foreach( $project->versions as $version)
    @foreach( $version->patches as $patch)
            {{ $patch->something }}
    @endforeach
@endforeach

但是当然会显示补丁,多个版本多次申请

如何在模型中定义这种关系并删除重复的补丁?我在找这样的东西(型号 \App\Project):

public function patches()
{
    return $this->hasManyThrough(
        'App\Patch',
        'App\Version',
        'projects_id',
        '???',
        'id'
    )->groupBy('patches.id');
}

我的模型中有以下方法:

项目

public function versions()
{
    return $this->hasMany('App\Version', 'projects_id');
}

版本

public function project()
{
    return $this->belongsTo('App\Project', 'projects_id');
}

public function patches()
{
    return $this->belongsToMany('App\Patch', 'versions_patches', 'versions_id', 'patches_id');
}

补丁

public function versions()
{
    return $this->belongsToMany('App\Version', 'versions_patches', 'patches_id', 'versions_id');
}

在您的项目模型中:

public function versions()
{
    return $this->hasMany('App\Version');
}

在您的版本模型中:

public function versions()
{
    return $this->hasMany('App\Patch');
}

在你的补丁模型中:

public function versions()
{
    return $this->belongsToMany('App\Patch');
}

要显示项目的所有 pacthes:(您的代码是正确的!)

@foreach( $projects->versions as $version)
    @foreach( $version->patches as $patch)
            {{ $patch->something }}
    @endforeach
@endforeach

但是上面的代码会产生N+1的问题,所以需要提前加载关系.

$projects = App\Project::with('versions.patches')->get();

Patch.php:

public function versions()
{
    return $this->belongsToMany('App\Version','versions_patches','patches_id','versions_id');
}

版本型号:

public function projects()
{
    return $this->hasMany('App\Project');
}

然后...

$projectPatches = $patches->whereHas('versions_id', function($q) use ($project) {
    return $q->where('projects_id',$project->version);
})->get();