用于多种类型用户的猫鼬模型

时间:2016-07-28 14:24:46

标签: javascript node.js mongodb mongoose email-verification

我正在为MEAN堆栈的学生和教师建立一种社交网络。

学生拥有自己的帐户页面,与其中一位教师不同。

我有一个教师和学生的注册页面。

注册时,用户必须选择带有select html标签(学生或教师)的帐户的“类型”,

我希望有一个单一模型代表两种不同类型的用户(教师和学生),其中包含电子邮件和密码等常用字段,以及一些特定字段,具体取决于select标签;因为我使用的是email-verification-node npm,它只允许在PersistentUserModel函数中使用单个模型。

2 个答案:

答案 0 :(得分:3)

在数据模型中设置一个布尔字段,该字段包含密钥教师(或学生,如果您愿意),并在用户注册时设置该字段。

编辑:

您可以拥有两种不同的架构,每种架构对应一种用户类型。声明它们看起来像这样。

const usersSchema = new Schema({/* base schema */});

const teachersSchema = new Schema({ /* teachers schema */});
const studentsSchema = new Schema({ /* students schema */});

const User = mongoose.model('User', usersSchema, 'users');
User.Teacher = mongoose.model('Teacher', teachersSchema, 'users');
User.Student = mongoose.model('Student', studentsSchema, 'users');

查看文档here

编辑2:

我发现更好的方法是使用鉴别器......谢谢!

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 = Event.discriminator('Teacher',
  new mongoose.Schema({/* Schema specific to teacher */}, options));
const studentSchema = Event.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! */});

通过致电教师或学生来查找

现在你有一个带有两个Schema的模型!更多信息,请参阅文档here.

使用更多信息进行修改:

您将创建两种类型的数据结构,即教师和学生,这两种数据结构都将保存在用户集合中。当您呼叫数据库时,您可以使用教师或学生进行呼叫。

任何两个共同的数据都会放在用户架构中,而任何特定的数据都放在相关的架构中。

当您接到api的电话时,您会直接进入相关的查询。您可以在请求参数中使用布尔值或字符串,然后使用if语句或switch语句将逻辑分离出来。我会用一个字符串和一个开关。

在您的客户端设置两个常量TEACHER ='老师',STUDENT ='学生',并使用相关常量调用您请求正文中的api。这样当它命中api时,请求将被解析为正确的查找并发回相关数据。

答案 1 :(得分:3)

我建议使用这种方法。

SchemasAccountTeacher应该有一个单独的Student,因此教师和学生之间的不同信息不应混合在一个地方。

帐户

var Account = new Schema({
    email:String,
    password:String,
    _teacher:{type:Schema.Types.ObjectId, ref:'Teacher'},
    _student:{type:Schema.Types.ObjectId, ref:'Student'}
})

在帐户下,如果教师帐户另有参考学生模型,则应参考教师模型。

要检查AccountTeacher还是Student,您只需检查_teacher,如果它有值,那么它是Teacher个帐户否则它就是学生。但要使条件更独特,请同时检查_teacher_student

如果您决定允许教师成为学生(这不是不可能发生),这种方法将在未来为您节省大量的重构,他/她可以使用相同的帐户并注册为一个学生。就像Google正在做的那样,通过帐号/电子邮件发送多种类型的应用。

<强>教师

var Teacher = new Schema({
    name:{type:Schema.Types.ObjectId, ref:'Name'}
    // Other teachers info
})

<强>学生

var Student = new Schema({
    name:{type:Schema.Types.ObjectId, ref:'Name'}
    // Other students info
})

命名

在这一部分,您可能想知道为什么需要一个单独的名称模型。那么这是因为在这种方法中,您只需使用一个routeendpointquery来搜索您应用中的用户。当您搜索姓名时,将查询所有具有匹配结果的学生和教师,而不会查看2个不同的集合(教师集合和学生集合)。

对于良好的用例,您肯定会有一个管理仪表板,您可以管理所有学生和教师。在该仪表板中,您只能为教师和学生提供一个搜索字段。

var Name = new Schema({
    firstName:String,
    middleName:String,
    lastName:String
})

好读

其他提示

您也可以像我一样将Address与此处的名称分开。原因?与Name的目的相同,您可能希望按位置功能或类似内容添加搜索。

我希望这会有所帮助。