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

davorminchorov's avatar

How do I connect the users table with students and teachers table so I can get data based on the account type?

Hey y'all, I have a question for you!

I am working on a personal project (Student Information System) for a university and I am planning how the access for the users of the application will work. I would like to be able to connect the users table with either students (if the user is a student) or teacher (if the user is a teacher).

So let's say that a student logs in the system, he/she should be able to see his grades, exam schedule his/her attendance information etc. Same goes for the teacher but the difference is that they should see all of their courses they teach and be able to grade a student, write down who attended or was absent from the class on a particular date and so on.

Currently, I am thinking that if I have a 1 to 1 polymorphic relationship between users and students and users and teachers, I won't have a problem figuring out if the logged in user is a teacher account or a student account, besides the roles specified in the system. I will be able to easily retrieve profile information (Grades about the student, courses that the teacher teach and is able to grade / write down attendance information about a specific class etc) about both types of users.

  • Am I on the right path?
  • Any ideas or advice?
0 likes
16 replies
jlrdw's avatar

Treat like an admin versus user where the teacher can see more but the student can see only his or hers. Should be able to do something there with guard.

davorminchorov's avatar

I am talking about retrieving data about the student while he/she is on, profile data. Same goes for the teacher. This case is something like 2 completely different profiles.

minjon's avatar

As far as I understand you have a group of students and a group of teachers and there is a many-to-many relationship between them. But I do not understand who the users are.

1 like
zachleigh's avatar

Wouldn't it be better to do away with the users table, just have students and teachers tables, and then connect the two through courses? So a student belongs to a course and a course belongs to a teacher. This way, teachers would be able to do things on a per course level, rather than for every student.

The only problem would be signing in. You would probably have to have separate signin forms for students and teachers. Most school sites Ive seen do this. They even have completely different home pages for both because the purpose for using the site is very different.

1 like
davorminchorov's avatar

Yeah that would be the idea, to connect students and teachers via courses using many to many relationships but let's say I have the following use case:

  • As a teacher, when I log in into the system, how would I be able to retrieve the courses I teach?
  • As a student, when I log in, how would I be able to retrieve the courses I am enrolled to and how can I see my personal grades when going to the profile page?

As I said before, I am looking for a way to connect the authenticated users with both teachers and students so the system knows that the user is a student and it should return student information about that account.

If I don't connect them somehow with a relationship, how will I know what students record to pull for Billy the student and what teacher records to pull for John the teacher?

ohffs's avatar

I'm doing much the same just now - students, academics, admin staff. I just have a flag on the user model (is_student etc) that's set based on their username. In my case students log in with a username based on their matriculation number, but staff have a 'real' username. Admin's are just flagged manually ontop of being staff.

Then after login there is just a test for if $user->is_student then show_student_homepage else show_staff_homepage. There are a couple of similar conditionals wrapped inside the relationship methods on the models too (eg, courses() if $this->is_student then return blah() else return blegh().

Not terribly elegant, but it works for the moment :-)

zachleigh's avatar

Teacher has many classes. Class has many students. Student belongs to many classes. Do you need a users table? I dont know...Id probably do it without one. Or you could do it like @ohffs and just have flag on the users model.

1 like
davorminchorov's avatar

That's not exactly what I am talking about. Let's say that a student can see only his own grades and classes, nothing else. That's all a student can see and do in this web app.

zachleigh's avatar

So use the out-of-the-box Laravel authentication. I usually go for a double lock-down, just to make sure everything is secure. In my model methods, I restrict everything and just throw exceptions/abort. In my controllers, I lock it down again but redirect with flash messages etc. for a nicer user experience. This way, if somehow somebody finds a hole in my controller authentication layer, the api can protect itself. You should probably also look into middleware authentication groups. You could have a teachers only section and a students only section so that students would never be able to get to the routes provided for the teachers. Laravel makes this sort of thing a breeze.

jlrdw's avatar

That is why I suggested doing something with guard., keeps the students seeing only what they are supposed to see. Doesn't have to be a user system guard still works probably anywhere you need it to.

Snapey's avatar

Personally, they are all users. Keep this for general access control. I would have a student flag and a teacher flag on the user model (they could be both of course).

Then do everything else through the menus and controllers.

If the student is logged in (user->is_student) then the 'My Grades' button is visible in the menu and the action takes you to /studentGrades and an appropriate controller and model.

If a teacher is logged in (user->is_teacher) then the 'My classes' button is visible and the action links to /teacherClasses and the appropriate controller.

The conflict only comes if you decide for instance that /profile should always be the url for the user's profile and that might need to branch. This can be easily managed by /studentProfile and /facultyProfile or similar.

Don't over-complicate / over-think things!

3 likes
rsands's avatar

as @Snapey has said, just a simple flag on the user of what type of account they are. Clean and simple

davorminchorov's avatar

Yeah, I get the roles part but I want to get something simple as auth()->user()->student()->grades or auth()->user()->teacher()->classes depending on the role they have. Also maybe add some special information about the dean of the faculty / school, so they can see maybe all of the classes etc.

I know it doesn't make much sense without going deeper into the problem, but that's just the idea behind the whole get data for authenticated user based on their role part.

ohffs's avatar

Why not just auth()->user()->classes and if they're a student it returns the classes they are enrolled on, otherwise it returns the classes they are teaching? Eg,

User Model :
public function courses()
{
    if ($this->isStudent()) {
        return $this->belongsToMany(Course::class, 'course_student');
    }
    return $this->belongsToMany(Course::class, 'course_staff');
}

You really only have two main 'roles' - student or staff. Then there are a few people who are 'staff++' who can then see extra 'Admin/Reports' menus & routes.

I've had code which works exactly like this for a $large_university for 6+ years and it's worked out fine :-)

davorminchorov's avatar

Yeah or that, but I am more interested in the isStudent() method, how do you determine if it's a student or a teacher? Is it based on the role the user has or it's a field (2 fields, one for student, one for teacher, maybe they are foreign key IDs?) in the database?

ohffs's avatar

When the account is created (either at login or when importing records) it checks their username and just sets a 'is_student' boolean on the entry. Student usernames are all of the form '1234567x' and staff are all 'abc123x' so it's easy to tell them apart. I can also fall back on their email address as students are all [email protected] whereas staff are just username@domain.

Ontop of that I make some assumptions - eg, when an admin is importing a list of students on a course I can just set is_student to true without checking.

So there is also a isStaff() method which is just return ! $this->isStudent().

Please or to participate in this conversation.