2016-06-16 4 views
0

У меня две модели: User и Businesses.Laravel eloquent - manyToMany, несколько «ролей» на сводном сводном столе

В бизнесе может быть много пользователей, а также бизнес может иметь много пользователей.

Например:

  • Джон является администратором для бизнес1.
  • John - суперадмин для Business2.
  • Mike является клиентом для Business1.
  • Mike является подписчиком на Business1.

Каков наилучший способ связаться с ними и запросить их позже.

Я построил таблицу business_user поворота и добавил Pivot столбцы

 $table->boolean('superadmin')->default(false); 
     $table->boolean('admin')->default(false); 
     $table->boolean('customer')->default(false); 
     $table->boolean('subscriber')->default(false); 

Является ли это путь, или я должен делать это по-другому? Только другая вещь, которая возникает, это разные сводные таблицы для каждого типа отношения, но это кажется плохой идеей.

Я бы запросить их как:

 $user->businesses()->wherePivot('subscriber',true)->get(); 

Я надеюсь, что я не пропускал синтаксис в любом месте, но если бы я сделал, пожалуйста, поправьте меня из-за других.

В следующем шаге также есть Redis.

ответ

1

Ваше решение отлично работает, но позже можно добавить некоторую гибкость (добавив больше ролей, определяя больше отношений с такими ролями, как разрешения и т. Д.), Вы можете рассмотреть следующее (обратите внимание, это также немного напоминает сложности, поэтому рассмотрим, нужна ли вам эта гибкость).

Создайте специальную модель для отношения (RoleAssignment), а также модель для разных ролей (Role). Затем RoleAssignment имеет три belongsTo отношения, Role, User и Business:

class RoleAssignment extends Model { 
    public function role() { 
     return $this->belongsTo(Role::class); 
    } 
    public function user() { 
     return $this->belongsTo(User::class); 
    } 
    public function business() { 
     return $this->belongsTo(Business::class); 
    } 
} 

class Role extends Model { 
    public function roleAssignments() { 
     return $this->hasMany(RoleAssignment::class); 
    } 
} 

class User extends Model { 
    public function roleAssignments() { 
     return $this->hasMany(RoleAssignment::class); 
    } 
    public function businesses($roleName = null) { 
     return $this->hasManyThrough(Business::class, RoleAssignment::class)->where('name'; 
    } 
} 

class Business extends Model { 
    public function roleAssignments() { 
     return $this->hasMany(RoleAssignment::class); 
    } 
} 

Запрос, который вы дали, то можно было бы записать в виде:

$user->roleAssignments()->whereHas('role', function ($query) { 
    return $query->where('name', 'subscriber'); 
})->with('business')->get()->pluck('business'); 

Чтобы упростить этот бит, вы может изменить ваше отношение roleAssignments на User модели принять необязательное имя роли:

class User extends Model { 
    public function roleAssignments($roleName = null) { 
     $relation = $this->hasMany(RoleAssignment::class); 
     if ($relation) { 
      $relation->whereHas('role', function ($query) { 
       return $query->where('name', 'subscriber'); 
      }); 
     } 
     return $relation; 
    } 
} 

Теперь вы можете написать запрос:

$user->roleAssignments('subscriber')->with('business')->get()->pluck('business'); 
+0

Спасибо за ваше время. Мне не нужна такая гибкость, но мне понадобятся пользовательские разрешения (Подписчик не может делать то же самое для бизнеса, что и администратор и т. Д.). Однако, я думаю, что это легко выполнимо с моей настройкой. Я буду изучать ваш пример более подробно, поскольку это то, что я буду в этом нуждаться в будущем. – dbr

Смежные вопросы