Laravel 7.0
Я пытаюсь настроить систему, в которой пользователи могут принадлежать к различным моделям, таким как курсы или области. Я называю это «членством».
У пользователя, который является участником Царства или Курса, всегда есть роль в этом Царстве, например «amdin», «editor» или «guest»
У меня есть модели для пользователей, ролей, членов и предметов курса / области.
Примерно так:
Role ⇦1:N⇦ Memberable ⇨N:1⇨ User
⇩
poly 1:1
⇩
Realm/Course/YouNameIt
В настоящее время я использую дикую смесь отношений, чтобы получить больше или меньше, чем я хочу. Но мой подход кажется мне довольно грубым или даже неправильным.
Например, чтобы получить список моделей, членом которых я являюсь, я пишу:
User::find(2)->memberships()->get()
Но это дает я Коллекция Счетов, а не Царств или Курсов, которые отстой. Можно ли это исправить?
Чтобы получить мой первый Царство / Курс, я должен написать:
User::find(2)->memberships()->first()->memberable // YUCK!
Вот мои модели:
class User {
public function memberships()
{
return $this->hasMany(Memberable::class)->with('memberable');
}
public function roles()
{
return $this->belongsToMany(Role::class, 'memberables')
->withPivot(['memberable_id', 'memberable_type']);
}
}
class Memberable extends Model
{
public function role()
{
return $this->hasOne(Role::class, 'id', 'role_id');
}
public function memberable()
{
return $this->morphTo('memberable');
}
}
trait HasMembers
{
public function members()
{
return $this->morphToMany(User::class, 'memberable', 'memberables')
->withPivot('role_id')
->join('roles', 'roles.id', 'memberables.role_id')
->addSelect(['role' => Role::select('name')
->whereColumn('role_id', 'roles.id')]);
}
}
class Realm extends Model
{
use HasMembers;
}
class Course extends Model
{
use HasMembers;
}
Я знаю, что на такие вопросы, как "это хорошо" или "это плохо", трудно ответить, поэтому я задам вопрос:
- Это так неправильно, что я должен волноваться ?
- Как мне улучшить этот дизайн?
- У меня, вероятно, никогда не будет больше моделей, чем областей и курсов, в которых могут быть участники. Разумнее ли отбросить весь мембранный полиморфизм в пользу двух отдельных таблиц? Приятно сохранять гибкость, которую предлагает подход polymorphi c.