I am building a kind of social network for students and teachers with MEAN stack.
Students has their own account page different from the one of the teachers.
I have one single registration page for both teachers and students.
When registering, the user has to choose the "type" of the account with a select html tag (student or teacher),
I want to have one single model representating two different type of user (teacher and student) that contains common fields like email and password etc, and some specific fields depending on the select tag ; because I am using email-verification-node npm and it only permits to use a single model in the PersistentUserModel function.
Mongoose Schema vs. Model. A Mongoose model is a wrapper on the Mongoose schema. A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
Mongoose is an ODM that provides a straightforward and schema-based solution to model your application data on top of MongoDB's native drivers.
ObjectId . A SchemaType is just a configuration object for Mongoose. An instance of the mongoose. ObjectId SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.
The mongoose. model() function of the mongoose module is used to create a collection of a particular database of MongoDB.
I suggest use this approach.
You should have a separate Schemas
for Account
, Teacher
and Student
so the different info between the teachers and students should not be mixed in one place.
Account
var Account = new Schema({
email:String,
password:String,
_teacher:{type:Schema.Types.ObjectId, ref:'Teacher'},
_student:{type:Schema.Types.ObjectId, ref:'Student'}
})
Under account, you should reference the Teacher model if teacher account otherwise reference Students model.
To check if Account
is Teacher
or Student
you could just check _teacher
, if it has a value then it's a Teacher
account else it's a student. But to make the condition more unique you, check both _teacher
and _student
.
This approach will save you a lot of refactoring in the future if you will decided to allow the teacher to be a student as well (which is not impossible to happen), he/she can just use the same account and register as a student. Just like what google is doing, on account/email multiple types of app to use.
Teacher
var Teacher = new Schema({
name:{type:Schema.Types.ObjectId, ref:'Name'}
// Other teachers info
})
Student
var Student = new Schema({
name:{type:Schema.Types.ObjectId, ref:'Name'}
// Other students info
})
Name
On this part maybe you are wondering why you need a separate model for name. Well that is because in this approach you can just use one route
or endpoint
or query
to search users across your app. When you search for a name, all students and teachers with matching result will be queried without looking into 2 different collections (Teacher collection and Student collection).
On good use case for this is, for sure you will have an admin dashboard where you can manage all students and teachers. In that dashboard you can just one search field for both teacher and student.
var Name = new Schema({
firstName:String,
middleName:String,
lastName:String
})
Good reads
Other tips
You could also separate the Address
like I did with the name here. Reason? Same purpose as with the Name
, you might want to add search by location feature or something like that.
I hope this helps.
Set up a Boolean field inside your data model that has the key teacher (or student if you prefer) and set that when the user signs up.
Edit:
You can have two different schemas, one for each user type. Declaring them would look something like this.
const usersSchema = new Schema({/* base schema */});
const teachersSchema = new Schema({ /* teachers schema */});
const studentsSchema = new Schema({ /* students schema */});
And
const User = mongoose.model('User', usersSchema, 'users');
User.Teacher = mongoose.model('Teacher', teachersSchema, 'users');
User.Student = mongoose.model('Student', studentsSchema, 'users');
Have a look at the docs here
Edit 2:
I found a better way of doing this is using discriminators...thanks!
const options = {discriminatorKey: 'kind'};
const userSchema = new mongoose.Schema({/* user schema */}, options);
const User = mongoose.model('User', userSchema);
// Schema that inherits from User
const teacherSchema = User.discriminator('Teacher',
new mongoose.Schema({/* Schema specific to teacher */}, options));
const studentSchema = User.discriminator('Student',
new mongoose.Schema({/* Schema specific to student */}, options));
const teacher = new Teacher({/* you can add everything here! */});
const student = new Student({/* you can add everything here! */});
Look up by calling either Teacher or Student
Now you have one model with two Schema! More info in the docs here.
Edit with more info:
You would create two types of data structure, a teacher and student which would both be held in the User collection. When you are calling the database you call using Teacher or Student.
Any data that is going to be common to both is put in the User schema, while anything that is specific you put in the relevant schema.
When you receive a call to the api you direct to the relevant look up. You could use a boolean or a string in the request params, and then separate out the logic with an if statement or a switch statement. I would use a string and a switch.
In your client set two constants TEACHER = 'teacher', STUDENT = 'student', and call with the relevant constant to the api in the body of your request. That way when it hits the api the request will be parsed to the correct lookup and send back the relevant data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With