Laravel Eloquent 用于数据透视表,一个表有 2 个外键,另一个表有 1 个外键

Posted

技术标签:

【中文标题】Laravel Eloquent 用于数据透视表,一个表有 2 个外键,另一个表有 1 个外键【英文标题】:Laravel Eloquent for pivot table with 2 foreign keys to a table and 1 foreign key to another table 【发布时间】:2020-12-30 18:34:49 【问题描述】:

我有如下表,其中role_idroles 表的外键,user_idsetter_idusers 表的外键。

table 1:
+---------------------+
| users               |
+---------------------+
| id                  |
| name                |
| email               |
| password            |
+---------------------+

table 2:
+---------------------+
| roles               |
+---------------------+
| id                  |
| name                |
+---------------------+

pivot table:
+---------------------+
| role_user           |
+---------------------+
| role_id             |
| user_id             |
| setter_id           |
+---------------------+

我定义的模型:

用户模型:

class User extends Model

    public $timestamps = false;
    
     public function roles()
     
         return $this->belongsToMany(Role::class);
     

榜样:

class Role extends Model

    public $timestamps = false;
    
    public function users()
    
        return $this->belongsToMany(User::class);
    

如何更改我的模型,以便获得如下所示的数据?

user -> roles -> setter : 用户及其角色以及用户每个角色的 setter

谢谢...

【问题讨论】:

请参考这里。 laravel.com/docs/7.x/eloquent-relationships#many-to-many 【参考方案1】:

您将永远无法通过在角色集合中调用 setter 来访问它。

这是错误的:

$user->roles->setter

让我们看一个可行的例子:

foreach($user->roles as $role)

    dd($role->pivot->setter)


要做到这一点,您需要更改模型以反映如下内容:

用户

class User extends Model

    public $timestamps = false;
    
     public function roles()
     
         return $this->belongsToMany(Role::class)
            ->using(UserRolePivot::class)
            ->withPivot([
                'role_id',
                'user_id',
                'setter_id',
            ]);
     

角色

class Role extends Model

    public $timestamps = false;
    
    public function users()
    
        return $this->belongsToMany(User::class)
            ->using(UserRolePivot::class)
            ->withPivot([
                'role_id',
                'user_id',
                'setter_id',
            ]);
    

枢轴

use Illuminate\Database\Eloquent\Relations\Pivot;

class UserRolePivot extends Pivot

    protected $fillable = [
        'role_id',
        'user_id',
        'setter_id',
    ];

    public function role()
    
        return $this->belongsTo(Role::class , 'role_id');
    

    public function user()
    
        return $this->belongsTo(User::class , 'user_id');
    

    public function setter()
    
        return $this->belongsTo(User::class , 'setter_id);
    

【讨论】:

【参考方案2】:

您可以更新 belongsToMany 调用以在枢轴上包含 setter_id,然后通过 ->pivot->setter_id 访问它并使用该 id 检索模型。

return $this->belongsToMany(Role::class)->withPivot('setter_id');

或者(以及我个人会选择的)您可以define a custom pivot model,并在那里创建setter() 关系,这样您就可以直接从枢轴检索模型。

【讨论】:

以上是关于Laravel Eloquent 用于数据透视表,一个表有 2 个外键,另一个表有 1 个外键的主要内容,如果未能解决你的问题,请参考以下文章

Eloquent ORM / Laravel - 使用自定义数据透视表结构

如何在 laravel 5 中使用 Eloquent 更新数据透视表

Laravel Eloquent 根据数据透视表字段条件获取多对多关系

Laravel Eloquent:我的数据透视表有关系

Lumen/Laravel Eloquent - 按数据透视表中的属性过滤

Laravel 数据透视表 id 列