Laravel 5:使用2个数据透视表连接3个表

时间:2015-03-12 08:30:15

标签: pivot-table laravel-5

我正在尝试查找与 a 表中的一行相关联的 c (请参阅数据库架构)中的所有行。由2个透视表连接,每个透视表具有 n:m 关系。

数据库架构:http://i.stack.imgur.com/t6HbB.png

以下是我定义关系的方式:

In model A: 
  $this->belongsToMany("App\B");

In Model B:
  $this->belongsToMany("App\A");
  $this->belongsToMany("App\C");

In model C:
  $this->belongsToMany("App\B");

我已经通过将方法 getC 添加到 A Eloquent模型中来实现目标:

public function getC() {
    $cCollection = new Collection();

    $this->b()->get()->each(function($b) use (&$cCollection){
        $b->c()->get()->each(function($c) use (&$cCollection) {
            $cCollection->add($c);
        });
    });

    return $cCollection;
}

它完美无缺,但它不符合我的要求。如果我构建一个新的集合,我无法对 C 表中的行进行分页等。如果有数千行,它也会很重。

如果我尝试做这样的事情:

A::findOrFail($id)->b

我收到 B 的集合,但我无法直接获得所有 C 。如果我迭代 B 的集合:

A::findOrFail($id)->b->each(function($b){
    $b->c();
});

我得到所有 C ,但我无法直接访问 C Eloquent,我无法对其进行计数,分页等等。

有没有其他方法可以做这样的事情?

A::findOrFail($id)->b->c->paginate(n);
A::findOrFail($id)->b->c->count();
A::findOrFail($id)->b->c->all();
etc...

1 个答案:

答案 0 :(得分:1)

供参考 - 其作者也在LARAVEL.IO接受了同样的答案。


摘录:

你需要的是一个"有很多很多"关系,但laravel不支持它。

以下是关于它的旧帖子:hasManyThrough with Many-To-Many

人们已经提出了一些解决方法,我可以为您提供另一个我认为非常干净的解决方法。它是在模型C

中嵌套whereHas的范围

模型C -

public function scopeHasAViaB($query, $ids) {
    if (empty($ids)) {
        return new \Illuminate\Database\Eloquent\Collection();
    }
    return $query->whereHas('b', function ($query) use ($ids) {
            $query->whereHas('a', function ($query) use ($ids) {
                $query->whereIn('id', $ids);
            });
        });
}

- 控制器代码 -

$modelAkeys = [1,2];
$cc = ModelC::HasAViaB($modelAKeys)->paginate(10);