Laravel Eloquent для сводной таблицы с 2 внешними ключами к таблице и 1 внешним ключом к другой таблице

#php #laravel #eloquent #pivot-table #laravel-7

#php #laravel #eloquent #сводная таблица #ларавель-7 #laravel-7

Вопрос:

У меня есть таблицы следующим образом, где role_id — внешний ключ roles таблицы, а user_id и setter_id — внешний ключ users таблицы.

 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);
    }
}
  

Как мне изменить свои модели, чтобы я мог получать данные, как показано ниже?

пользователь -> роли -> установщик: пользователь и его роли и установщик каждой роли для пользователя

Спасибо…

Комментарии:

1. Пожалуйста, обратитесь к этому. laravel.com/docs/7.x/eloquent-relationships#many-to-many

Ответ №1:

Вы никогда не сможете получить доступ к установщику, вызвав его в коллекции ролей.

Это неправильно:

 $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 IlluminateDatabaseEloquentRelationsPivot;

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 и получить модель, используя этот идентификатор.

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

Или (и на что я бы лично пошел) вы могли бы определить пользовательскую сводную модель и создать setter() связь там, чтобы вы могли извлекать модель непосредственно из сводной таблицы.