如何通过多态关系将关系写入到远程模型

Posted

技术标签:

【中文标题】如何通过多态关系将关系写入到远程模型【英文标题】:How to write a relationship to a distant model through a polymorphic relation 【发布时间】:2019-08-31 01:31:20 【问题描述】:

我有一个多态关系,其中类(请求)可以与类(离开)或类(加班)有关系。

类 (Request) 的每个对象都属于一个用户。

我想在 User 类中建立一个关系来直接获取他们所有的 Leave 或 Overtime 对象。


代码如下:

类请求: user_id requestable_id requestable_type 可以是 App\Leave 或 App\Overtime
    class Request extends Model
    
        public function requestable() 
            return $this->morphTo();
        

        public function user() 
            return $this->belongsTo('App\User');
        
    

课假
    class Leave extends Model
    
        public function request() 
            return $this->morphOne('App\Request', 'requestable');
        
    

上课加班
    class Overtime extends Model
    
        public function request() 
            return $this->morphOne('App\Request', 'requestable');
        
    

类用户
    class User extends Authenticatable
    
        public function requests() 
            return $this->hasMany(Request::class);
        

        public function leaves() 
            // Need help here
        

        public function overtimes() 
            // And here
        
    


我想做的是获得用户的所有休假和加班,所以最终我应该能够做到这一点:

    $userLeaves = $user->leaves;
    $userOvertimes = $user->overtimes;

【问题讨论】:

hasManyThrough 关系是您正在寻找的吗? laravel.com/docs/5.8/eloquent-relationships#has-many-through。或者你可以使用 ->hasMany()->where(); 你能试一试吗?我认为它不适用于多态关系 【参考方案1】:

似乎您需要多态关系(您已经定义)和 hasManyThrough 的组合。 return $this->hasManyThrough(Leave::class, Request::class);return $this->hasManyThrough(Overtime::class, Request::class); 分别。但是检查外键和本地键(查看更多信息here)。

【讨论】:

是的,我相信 hasManyThrough 是解决方案,但无论我尝试使用多少种外/本地键组合,我都无法让它工作,也许可以试一试? 我从来没有使用过这种关系。也许您需要指定相关多态模型的类型。尝试使用this。【参考方案2】:

您可以通过用户请求获取用户休假和加班使用

$requests = $user->requests->with('requestable');

但这将获取所有用户请求,而不取决于类型,但是您可以根据需要使用叶子和超时函数根据类型获取它们并在此处指定类型

用户类

public function leaves()

    return $this->requests->where('requestable_type', 'App\Leave');


public function overTimes()

    return $this->requests->where('requestable_type', 'App\OverTime');

【讨论】:

但这将返回Request类型的对象,而不是休假或加班的对象【参考方案3】:

回答我自己的问题。

使用hasManyThrough

public function leaves() 
    return $this->hasManyThrough(
        Leave::class, // the class that we want objects from
        Request::class, // the class sitting between this one and the target
        'user_id', // this class's foreign key in the request class
        'id', // foreign key in leave class
        'id', // local key in this class
        'requestable_id' // key of the leave in the request class
        )
        // we have to limit it to only Leave class
        ->where('requestable_type', array_search(Leave::class, Relation::morphMap()) ?: Leave::class);


public function overtimes() 
    return $this->hasManyThrough(
        Overtime::class, // the class that we want objects from
        Request::class, // the class sitting between this one and the target
        'user_id', // this class's foreign key in the request class
        'id', // foreign key in overtime class
        'id', // local key in this class
        'requestable_id' // key of the overtime in the request class
        )
        // we have to limit it to only overtime class
        ->where('requestable_type', array_search(Overtime::class, Relation::morphMap()) ?: Overtime::class); 

【讨论】:

请mark the answer as accepted。这会向其他用户显示问题已解决。

以上是关于如何通过多态关系将关系写入到远程模型的主要内容,如果未能解决你的问题,请参考以下文章

将两个 JSON 文件中的数据写入具有关系的核心数据模型

Rails:如何创建多态关系/友谊模型

如何模拟不同的模型来检索多态关系?

如何渴望加载多态关系的不同嵌套关系?

(Laravel)通过数据透视表的多态关系

多态关系的 MagicalRecord 导入