【问题标题】:HasMany Relation through BelongsToMany RelationHasMany 关系通过 BelongsToMany 关系
【发布时间】:2019-10-01 16:38:25
【问题描述】:

Laravel 是否可以通过 belongsToMany 关系来建立关系?

我有 4 张桌子:

1)Restaurants (id , name) - 将 hasManyRelation 与 Workers 表一起使用

2)董事(id,姓名)

3)Directors_Restaurants (id, director_id, restaurant_id) - 用于将 belongsToMany 餐厅与董事联系起来的数据透视表

3)Workers (id, name, restaurant_id)

通过 Director 模型中的此功能,我可以获得所有连接的餐厅

public function restaurants()
{
    return $this->belongsToMany('App\Restaurant','director_restaurant');
}

通过我的代码中的这个函数,我可以得到一个董事所有餐厅的所有工人

$director = Director::find(1);
$director->load('restaurants.workers');
$workers = $director->restaurants->pluck('workers')->collapse();

所以我的问题是:我可以在我的 Director 模型中声明类似的关系以获取所有餐厅的所有工人吗?

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    当然你可以在Director模型上使用hasMany关系方法和Eager Loading

    如下图

    public function restaurants()
    {
        return $this->hasMany(Restaurant::class)->with('restaurants.workers');
    }
    

    【讨论】:

    • 感谢您的回答!
    【解决方案2】:

    我可以建议这样的解决方案:

    导演模型选项 1

    public function getAllRestaurants(){
        return $this->hasMany(Restaurant::class)->with('restaurants.workers');
    }
    

    导演模型选项 2

    public function getAllRestaurants(){
        $this->load('restaurants.workers');
        return $this->restaurants->pluck('workers')->collapse();
    }
    

    您可以在任何地方找到所有餐厅

    $all_restaurants = Director::find(1)->getAllRestaurants();
    

    【讨论】:

    • 感谢您的回答,OPTION2 正是我所需要的。还有一个问题:使用函数'load(something.othersomething)' a 可以引用我模型中的任何关系吗?甚至从另一个关系中引用一个关系?
    • 是的,您可以引用模型的任何关系。只要确保所有外键都设置好。
    【解决方案3】:

    您可以通过“跳过”restaurants 表来定义直接关系:

    class Director extends Model
    {
        public function workers()
        {
            return $this->belongsToMany(
                Worker::class,
                'director_restaurant',
                'director_id', 'restaurant_id', null, 'restaurant_id'
            );
        }
    }
    

    【讨论】:

    • 谢谢,但出现“BelongsToMany 无法转换为字符串”异常。
    • 你是如何使用它的?
    • 这样:$director = Director::find($id);返回 $director->workers();
    • 使用return $director->workers;return $director->workers()->get();laravel.com/docs/eloquent-relationships#querying-relations
    【解决方案4】:

    你可以在你的模型中定义一个accessor方法来隐藏一些逻辑

    # App/Director.php
    
    // You'll need this line if you want this attribute to appear when you call toArray() or toJson()
    // If not, you can comment it
    protected $appends = ['workers'];
    
    public function getWorkersAttribute()
    {
        return $this->restaurants->pluck('workers')->collapse();
    }
    
    # Somewhere else
    $director = Director::with('restaurants.workers')->find(1);
    $workers = $director->workers;
    
    

    但最终,您仍然需要加载嵌套关系 'restaurants.workers' 才能使其工作。

    根据您的表属性,您还可以定义一个自定义的HasMany 关系,如下所示

    # App/DirectorRestaurant.php
    
    public function workers()
    {
        return $this->hasMany(Worker::class, 'restaurant_id', 'restaurant_id');
    }
    
    # Somewhere else
    $director = Director::find(1);
    $workers = DirectorRestaurant::where('director_id', $director->id)->get()->each(function($q) { $q->load('workers'); });
    
    

    但我不推荐它,因为它的可读性不是很好。

    最后,您可以在 staudenmeir/eloquent-has-many-deep 包中定义这种嵌套关系。

    https://github.com/staudenmeir/eloquent-has-many-deep

    【讨论】:

      猜你喜欢
      • 2014-12-30
      • 2021-03-22
      • 2018-01-03
      • 2021-10-07
      • 2022-01-16
      • 2020-03-04
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      相关资源
      最近更新 更多