Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

P-James's avatar
Level 12

Eloquent relationships between different types of User (based on Role)

First off, apologies, because I can see this topic is discussed on the forum pretty regularly. However I'm struggling to find an answer that can clarify the best way to go about this for me.

I have roles set up. My roles are :

Admin, Teacher, Student.

They are all just Role models linked to Users in role_user table.

Ultimately I want to set up relationships between different types of Users.

Teacher belongsToMany Students  
Students belongsToMany Teachers

I'll also have other models like Group which are different per Role.

Teacher hasMany Groups
Student belongsToMany Groups

Is it possible to set these relationships up when they are all on the Users table?

I have a feeling I should either 1. be extending the User model for this, or 2. maybe morphing a type of Role to the User (I'm not too familiar with polymorphism).

Can anyone push me in the right direction?

0 likes
5 replies
bobbybouwmann's avatar

Yeah, this is a perfect example of a polymorphic relationship.

However, I would personally not create different Teacher and Student models. In the end, they are all users. I would probably create a user's table and have a many-to-many relationship between a user and a role. So a user can be both a teacher and a student at the same time in theory.

If the user can only have one rule, then I would store the role simply on the user itself and have a many-to-many relationship between the user and the group.

1 like
P-James's avatar
Level 12

@bobbybouwmann Thanks for reading/ replying.

I have the roles set up as many-to-many relationships, I actually implemented it exactly as Jeffrey explains here https://laracasts.com/series/laravel-6-from-scratch/episodes/54

I'm just confused about relationship clashes, eg:

// App\User
// Teacher (User) has many classes.
    public function classes()
    {
        return $this->hasMany(Group::class, 'teacher_id');
    }

// Student (User) belongs to many classes.
    public function classes()
    {
        return $this->belongsToMany(Group::class);
    }

As these are all just Users, is it acceptable to rename the methods (to avoid a clash) and peform a check before the relationships like:

    // App\User
    // Teacher has many classes.
    public function classesOfStudents()
    {
        if ($this->hasAnyRole(['teacher', 'admin'])) {
        return $this->hasMany(Group::class, 'teacher_id');
        }
    }

    // Student can be in many classes.
    public function studyGroups()
    {
        if ($this->hasAnyRole(['student'])) {
            return $this->belongsToMany(Group::class);
        }
        
    }
bobbybouwmann's avatar
Level 88

Yeah, that is perfectly fine but I always find this very confusing in your models in the end. Would you still understand this code in 6 months?

I always try to keep my relationships as simple as possible. So no Student or Teach class. Just a user that belongs to many x. Keep in mind that I don't know all of your requirements and restrictions.

1 like
P-James's avatar
Level 12

Thanks man. It's great to have another dev's insight.

I will give it a shot at writing something more readable using only a User model.

If I come up with something I'm happy with I will comment it here to help others.

Please or to participate in this conversation.