发布于: 2022-06-06 14:04:35
  1. 通过pivot属性来访问关联表的字段

  2. $user = App\User::find(1);

  3. foreach ($user->roles as $role) {

  4. echo $role->pivot->created_at;

  5. }


  6. 中间表可能不仅仅包含两个表的外键,还有一些附加的字段,举个例子:

  7. 一个用户可以属于多个部门,即用户和部门是多对多关系,一个用户在不同部门里角色可能不一样,即用户和角色也是多对多。这个中间表的结构如下:

  8.  

  9. +---------------+------------------+------+-----+---------+----------------+
    | Field         | Type             | Null | Key | Default | Extra          |
    +---------------+------------------+------+-----+---------+----------------+
    | id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | user_id       | int(10) unsigned | NO   |     | NULL    |                |
    | role_id       | int(10) unsigned | NO   |     | NULL    |                |
    | department_id | int(10) unsigned | NO   |     | NULL    |                |
    | created_at    | timestamp        | YES  |     | NULL    |                |
    | updated_at    | timestamp        | YES  |     | NULL    |                |
    +---------------+------------------+------+-----+---------+----------------+

获取一个用户在所有部门所对应的角色时:

 

foreach($user->departments as $department) {
$role = Role::find($department->privot->role_id);
}

可以看到步骤还是比较繁琐,如果这个pivot能像别的Model那样直接通过$department->privot->role来拿到角色信息就会方便很多。

研究了一下Laravel的代码,发现是可以实现的,首先新建一个类

 

namespace App\PivotModels;
use Illuminate\Database\Eloquent\Relations\Pivot;
use App\Models\Role;use App\Models\Department;
class UserRole extends Pivot{
    public function role(){
        return $this->belongsTo(Role::class);
    }
    public function department(){
        return $this->belongsTo(Department::class);
    }
}

然后在App\Models\Department类中重写newPivot方法:

 

public function newPivot(Model $parent, array $attributes, $table, $exists)
{
if ($parent instanceof User) {
return new UserRole($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}

修改App\Models\User类中的departments方法:

 


public function departments()
{
return $this->belongsToMany(Department::class, 'user_role', 'department_id', 'user_id')
->withPivot(['department_id', 'user_id', 'role_id']) // 这行要把中间表的字段都加上
->withTimestamps();
}


延伸阅读
    发表评论