Multi user type model and auth

Published 3 months ago by mix359

Hi to all,

I've a strange situation, that initially seam simply, but it's really complicated to approach. I've to create a system that it's used in a school, so that have 3 different types of users:

  • Student
  • Parent
  • Teacher/Personal

My initial idea was to use 3 different Models/tables, one for user type. In this way is more simple to write many of the relation and controller code. And for the moment this approach worked, because I was only having the teacher/personal to login into the system. But now I have to permit the login of the students and the parents, that should see different thing, etc

To do that I've see to way, but I don't know which is the best/clearest:

First way is to use a common Account model, where all the users is, and a flag on the table that represent the user type. Then I will have the other 3 Model (Teacher, Student, Parent) extend the Account model, pointing to the accounts table, and having something like that:

public function newQuery() {
        return parent::newQuery()->where('type', Account::ACCOUNT_TYPE_TEACHER); 
}

So every generic query that I made on the model, is filtered as a teacher.

I've used a similar approach in the past, and have worked well, but the situations was simpler that this.

In this way I've probably a better situation for the authentication and permission management, because I have the same basic Account for all the type of users, but this should probably create some more complex query.

Also I have to do other table that contain the data that is not shared from the various types of users: for example, a student have some information about his curriculum. And the difficult part is that I need some intermediary join table to some other table, for example a student will have a classroomId, and I need to have an intermediate table with studentId - classroomId. Or even more complex, a parent have a relation with the student, that is also in the same table.

Second way, have the three different Model and table for every user type. The pro of this solution is that I can have the "extra" field (that are not shared from the various user types) directly on the table, so I will have simpler relations and join.

The cons is that I have to use a multi-auth system, and I have to keep track in all the code and all the other Model of the user type. For example, if I need to save on an entity the user that created it, I have to save the user type, and the id of that user in his table (that change from type to type)

That make also more difficult to manage the authorization/permission in the code, because I have to check the user type to select the correct user model, and then I can use the user id. So I need to modify or use a different auth system.

Thanks to all that can help me make this decision

I wish that this post is clear enough to understand what I'm trying to do :)

Cheers Daniele

ctroms

Just another thought which kind of a combination of your two suggestions...

Create account_types or profiles tables for each user type Student, Parent, Teacher/Personal.

Store all users in a single users table with the attributes needed for authentication (e.g. email, password, reset token, etc) and a two additional columns (profile_id, profile_type) to store a polymorphic relationship.

Then define a polymorphic relationship (maybe profiles) on your users model to the profile models.

When you query a user for simple authentication, you most likely are not interested in the profile data (e.g. firstname, lastname, etc), just the email, password which would all be present on the user table.

When you want to check permissions for a user, you can check the profile_type column on the user table to determine the account type.

If you want all users that are teachers, students or parents, define scopes on your users model to check the profile_type column to handle that.

While relationships between two entities on the same table are totally valid, you can create your relationships between account types to their respective profile models. So the parent model has a relationship to the student model, etc.

I'm not suggesting that this is better or worse than any other ideas you have or may hear, just another alternative.

extjac

The way i would do this is by using the users table to manage login/password and user type (Student, Parent, Teacher/Personal). Then I would have a people table where I would store the personal data such as first_name, last_name, etc.. maybe a parent_id where i would store the relationship between the username/password. Then i would have tables like: people_relationships where you could store who is the parent/child, who is the teacher/boss, etc. etc. etc Then you can just create relationships/models

jekinney

Similar to what @extjac said.

Many time our apps require specific data for user types. With that in mind I set the user table to the bare minimum of what's need with out duplication in the other types. Keep in mind when you auth check your hitting the database. So if your app (for example) requires extensive profile data, but rarely require it, probably beneficial to have a separate table.

In your case, if a teacher versus student etc have specific requirements then each having a related table but one user table (for auth check and faster queries) might be beneficial, and ultimately simplier. If the data is minimal and redundant the using an acl (role and/or permissions) is probably the way to go.

Splitting up your users into completely different tables, I argue is not simpler and adds complexity and confusion. A user is a user, what type of user is still a user.

Always think: what if a teacher takes a class so then becomes a student?

Snapey
Snapey
3 months ago (520,165 XP)

I don't really understand why people make this choice of 'classes' of user and think they need to create multiple login methods.

They are all users of your application, why make it harder by splitting them into different models?

A simple type on the User model can tell you what class of user they are and allow a link to different 'profile' models if you need to store multiple different attributes per user type.

Then do everything else through authorization.

mix359

Thanks for the various answer :) I'm still thinking which solution to use, but some other point of view is interesting ;)

I'm trying to find a way to compare the various solution... maybe I can try to calculate the type and number of query that Eloquent should be do in the various situation... (If it's not too hard/long to do xD) There are some way to predict the result of a test like that? (without creating all the 3 structure, populate with random data and see the query number/time?)

To answer to @Snapey, yes they are all user of my application, watching from the authentication/permission point of view. Looking from other point, it could be something totally different.

For example, if I need to select the users of a classroom, the teacher have particular relation: the teacher-subject-classroom relation. The student have a direct relation with the classroom. The parent should be related to their child and then their child to the classroom.

For the 3 different types of user I have 3 different way to relate to other model. And in many part of my application I need to see they as Teacher, or Student, not as User.

I don't have only simple attributes or profile data to attach to the user. I have relation (and function) and it's different from user type to user type. So I need to have a Model for every type of user, where I can create relation and function that it's unique to that type of user (and the relation can be reversed in other Model, calling for example only the students).

Thanks again Cheers Daniele

Snapey
Snapey
3 months ago (520,165 XP)

Your comments are perfectly rational and sensible. Given what you said, I would probably go for a single authentication only user model and then implement a model per type of user so that, as you say, you can keep the relationships clean.

ctroms

It sounds like regardless of which method you select, everyone so far is suggesting a single user model for authentication. The only variance in responses are how you relate the user profile data to the user account and all are perfectly valid. Based on what I think you are after from your comments, I agree with @snapey on how to structure the profiles.

vipin93

Here I working on same project Idea, here is the problem with using same tables for may be teachers does not have same information columns as students, So I have done that make model for User(Super admin or manager of college /school), Teacher /Employee (like fee collection, management) and Student/Parents, And made two more auth gaurd, and I make Type of teacher/employee, then Employees cab registered student and teacher

Sign In or create a forum account to participate in this discussion.