如何在Laravel中使用超过3个表的'hasManyThrough'?

时间:2016-01-22 13:29:44

标签: laravel orm eloquent relational-database

docs中所述,当您有类似country > users > posts

的内容时,可以使用当前的 hasManyThrough

导致类似Country::whereName('xx')->posts;的内容 这很棒,但如果我有更多的东西呢

country > cities > users > posts 甚至

country > cities > towns > users > posts

你将如何实现类似的东西,以便你可以像上面那样写出

Country::whereName('xx')->posts;Town::whereName('xx')->posts;

3 个答案:

答案 0 :(得分:3)

我创建了一个HasManyThrough级的无限关系:Repository on GitHub

安装后,您可以像这样使用它:

class Country extends Model {
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function posts() {
        return $this->hasManyDeep(Post::class, [City::class, Town::class, User::class]);
    }
}

答案 1 :(得分:2)

这就是我所做的。我对@ ctfo的回答做了一些修改,所以它将作为集合返回。

public function posts()
{
    $posts = collect();

    foreach ($this->towns->get() as $town) {
        $post = $town->posts();
        if ( $post->count() ) $posts = $posts->merge( $post );
    }

    return $posts;
}

我希望这可以帮助任何人过来。

答案 2 :(得分:1)

遗憾的是,没有一个简单的解决方案,所以我发现了

1-将另一个表外来ID添加到帖子表中并坚持 hasMany & belongsTo ,例如

posts
    id - integer
    country_id - foreign
    // etc...
    title - string

2-除了user&之外的每张桌子上的 hasManyThrough post除非你想深入,否则没有必要,例如

countries
    id - integer
    name - string

cities
    id - integer
    country_id - foreign
    name - string

towns
    id - integer
    city_id - foreign
    name - string

users
    id - integer
    town_id - foreign
    name - string

posts
    id - integer
    user_id - foreign
    title - string
  

- 所以让我们试试第二个选项

1-设置 hasMany &像往常一样属于关系

2-在模型上设置 hasManyThrough

3-实现Country::whereName('xx')->posts的上述示例我们在国家模型中添加了另一种方法

// because Country::find($id)->towns, return an array
// so to get all the posts we have to loop over that
// and return a new array with all the country posts
public function posts()
{
    $posts = [];

    foreach ($this->towns as $town) {
        $posts[] = $town->posts;
    }

    return $posts;
}

4-因为整个事情正在通过 foreign_id 进行,所以我们使用 id 而不是 进行搜索名称 ,例如Country::find($id)->posts()