How to use 'hasManyThrough' with more than 3 tables in Laravel?

帅比萌擦擦* 提交于 2020-12-29 23:34:58

问题


as stated in the docs the current hasManyThrough can be used when u have something like country > users > posts

which result in something like Country::whereName('xx')->posts; which is great but what if i have more than that like

country > cities > users > posts or even

country > cities > towns > users > posts

how would you then implement something like that so you can write the same as above

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


回答1:


I created a HasManyThrough relationship with unlimited levels: Repository on GitHub

After the installation, you can use it like this:

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

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



回答2:


Here's what I've done. I did some modification to @ctfo's answer, so it will return as collection.

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

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

    return $posts;
}

I hope this can help anyone who came through.




回答3:


sadly there is no one easy solution, so heres what i found

1- add the other table foreign id into the post table and stick to the hasMany & belongsTo, ex.

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

2- go with the hasManyThrough on each table except user & post as there is no need unless you want to go deeper, ex.

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

- so lets try with the 2nd option

1- set up your hasMany & belongsTo relations as usual

2- setup the hasManyThrough on the models.

3- to achieve the above example of Country::whereName('xx')->posts we add another method to the country model

// 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- as the whole thing is working through the foreign_id so we search by the id instead of the name like Country::find($id)->posts()



来源:https://stackoverflow.com/questions/34947862/how-to-use-hasmanythrough-with-more-than-3-tables-in-laravel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!