HasManyThrough 具有多态和多对多关系

Posted

技术标签:

【中文标题】HasManyThrough 具有多态和多对多关系【英文标题】:HasManyThrough with polymorphic and many-to-many relations 【发布时间】:2016-08-06 11:11:56 【问题描述】:

在我的 Laravel 应用程序中,我有以下类:

class Product extends Model

    public function extended()
    
        return $this->morphTo();
    

    public function users 
        return $this->belongsToMany('App\User', 'products_users', 'product_id');
    


class Foo extends Model 

    public function product()
    
        return $this->morphOne('App\Product', 'extended');
    
    public function bars()
    
        return $this->hasMany('App\Bar');
    


class Bar extends Model 

    public function product()
    
        return $this->morphOne('App\Product', 'extended');
    

    public function foo()
    
        return $this->belongsTo('App\Foo');
    


class User extends Model

    public function products()
    
        return $this->belongsToMany('App\Product', 'products_users', 'user_id');
    

我可以使用Bar::find(1)->product->users 轻松获取bar 对象的用户,也可以使用User::find(1)->products 获取用户的bar。

如何获取属于特定 foo 的所有 bar 的用户?也就是说,Foo::find(1)->users 应该返回所有拥有属于 Foo 且 id 为 1 的条的用户。它基本上是具有多态和多对多关系的 hasManyThrough。

【问题讨论】:

【参考方案1】:

试试这样的:

public function users()
    
        $Foo = static::with(['bars', 'bars.products', 'bars.product.users'])->get();
        return collect(array_flatten(array_pluck($Foo, 'bars.*.product.users')));
    

应该为您工作(代码已经过测试,但与您的设置的结构不完全相同)。第一行将返回所有通过关系深度嵌套的用户。第二行将拉出用户,将它们展平为数组,然后将数组转换为集合。

【讨论】:

这似乎包括与给定 Foo 无关的用户 使用find 语句而不是get 语句然后:$Foo = static::with(['bars', 'bars.products', 'bars.product.users'])->find($this->id);(假设您的主键是id【参考方案2】:

我为以下情况创建了HasManyThrough 关系:Repository on GitHub

安装后,可以这样使用:

class Foo extends Model 
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function users() 
        return $this->hasManyDeep(
            User::class,
            [Bar::class, Product::class, 'products_users'],
            [null, ['extended_type', 'extended_id']]
        );
    

【讨论】:

以上是关于HasManyThrough 具有多态和多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent: hasManyThrough 多对多关系

具有一对多和多对多关系的 JOOQ pojos

Laravel:具有 whereHas 和多对多关系的全局范围

具有外键和多对多关系的 Django 模型与同一模型

QueryDSL 和多对多关系

Typegoose 模型和多对多关系