2015-12-21 28 views
0

我正在使用Mongoose在Express中设置Mongo数据库,并试图决定如何为用户建模。我以前从未在MEAN堆栈中模拟过多个用户,并且认为我会接触到一些最佳实践 - 我是一名讲师,需要能够教会学生的最佳实践。我没能在那里找到很多东西,但也许我正在寻找错误的东西。具有三种用户类型的Mongo用户文档结构

该应用将有3种用户类型,student,staffadmin。每个用户类型需要一些相同的基础知识 - 电子邮件,密码,名字和姓氏,电话等。如果用户是student,他们将需要提供其他信息,如他们的高中名称,年级,年龄,性别,等等,理想情况下将是必需的。

这是我到目前为止所提出的 - 一个单一的用户模型,需要所有的基本信息,但也有架构设置,以允许学生需要包含的额外信息。然后我也有一个预存挂机设置,如果被保存在用户没有一个“学生”角色删除“studentInfo”子文档:

var mongoose = require("mongoose"); 
var Schema = mongoose.Schema; 

var ethnicityList = [ 
    "White", 
    "Hispanic or Latino", 
    "Black or African American", 
    "Native American or American Indian", 
    "Asian/Pacific Islander", 
    "Other" 
]; 

var userSchema = new Schema({ 
    firstName: { 
     type: String, 
     required: true 
    }, 
    lastName: { 
     type: String, 
     required: true 
    }, 
    phone: { 
     type: Number, 
     required: true 
    }, 
    email: { 
     type: String, 
     required: true, 
     lowercase: true, 
     unique: true 
    }, 
    password: { 
     type: String, 
     required: true 
    }, 
    preferredLocation: { 
     type: String, 
     enum: ["provo", "slc", "ogden"] 
    }, 
    role: { 
     type: String, 
     enum: ["student", "staff", "admin"], 
     required: true 
    }, 
    studentInfo: { 
     school: String, 
     currentGrade: Number, 
     ethnicity: { 
      type: String, 
      enum: ethnicityList 
     }, 
     gender: { 
      type: String, 
      enum: ["male", "female"] 
     } 
    } 
}, {timestamps: true}); 

userSchema.pre("save", function (next) { 
    var user = this; 
    if (Object.keys(user.studentInfo).length === 0 && user.role !== "student") { 
     delete user.studentInfo; 
     next(); 
    } 
    next(); 
}); 

module.exports = mongoose.model("User", userSchema); 

问题1:这是一个不错的方法要做到这一点,还是仅仅创建两种不同的模型并将它们完全分开是更好的选择?

问题2:如果我将要限制通过它们的用户访问类型的用户,这将是很容易受到用户的role属性与上面的设置进行检查。但是,如果最好为不同的用户类型使用不同的模型/集合,我该如何检查它是否尝试访问受保护资源的“职员”或“学生”?

问题3:看来,如果我按照上面所述的方式进行设置,我无法对子文档进行某些验证 - 我想要求学生填写子文档中的信息,但不要求人员或管理员用户。当我将任何字段设置为required时,即使子文档本身不是必需的,但它们在未包含时仍会引发错误。 (这是有道理的,但我不知道如何解决,也许自定义验证预保存?我以前从来没有写过,所以我不知道如何,但我可以看看,如果这是最好的)

+0

如果你教CS,你可能会对新的[CS Educator's Stack Exchange](http://cducator.stackexchange.com)感兴趣(虽然它仍然在私人测试版中,但是通过这里](https://area51.stackexchange.com/proposals/92460/computer-science-educators)) –

回答

1

那么,这是我的两分钱。

  1. 您最好创建单独的模式模型,然后根据需要注入模型。

例如, 如果我有一个博客的模式如下:

 var createdDate = require('../plugins/createdDate'); 

    // define the schema 
      var schema = mongoose.Schema({ 
       title: { type: String, trim: true } 
       , body: String 
       , author: { type: String, ref: 'User' } 
      }) 

// add created date property 
schema.plugin(createdDate); 

请注意,笔者指的是User并且有一个附加字段createdData

这里是用户模式:

var mongoose = require('mongoose'); 
var createdDate = require('../plugins/createdDate'); 
var validEmail = require('../helpers/validate/email'); 

var schema = mongoose.Schema({ 
    _id: { type: String, lowercase: true, trim: true,validate: validEmail } 
    , name: { first: String, last: String } 
    , salt: { type: String, required: true } 
    , hash: { type: String, required: true } 
    , created: {type:Date, default: Date.now} 
}); 

// add created date property 
schema.plugin(createdDate); 

// properties that do not get saved to the db 
schema.virtual('fullname').get(function() { 
    return this.name.first + ' ' + this.name.last; 
}) 

module.exports = mongoose.model('User', schema); 

而且在用户和Blogspot中正在评估的已创建财产

// add a "created" property to our documents 
module.exports = function (schema) { 
    schema.add({ created: { type: Date, default: Date.now }}) 
} 

如果你想根据用户类型来限制访问,您必须编写自定义的验证就像我们已经为电子邮件编写的用户模式:

var validator = require('email-validator'); 

module.exports = function (email) { 
    return validator.validate(email); 
} 

,然后添加一个if-else的,不管以何种验证你做的。

2和3.所以,是的自定义验证也预先保存。

由于您是一名讲师,我更愿意指出所使用的做法,而不是详细说明您的具体问题。

希望这会有所帮助! :)

相关问题