Mongo用户文档结构有三种用户类型

时间:2015-12-21 14:41:33

标签: node.js mongodb authentication express mongoose

我正在使用Mongoose在Express中设置一个Mongo数据库,我正在尝试决定如何为用户建模。我以前从未在MEAN堆栈中为多个用户建模,并且认为我会接触到一些最佳实践 - 我是一名教师,需要能够教会我的学生最佳实践。我一直无法找到很多,但也许我正在寻找错误的东西。

该应用将有3种用户类型,studentstaffadmin。每种用户类型都需要一些相同的基础知识 - 电子邮件,密码,姓名,电话等。如果用户是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时,即使不需要子文档本身,它也会在未包含时抛出错误。 (这是有道理的,但我不知道如何解决。也许自定义验证预先保存?我以前从未写过,所以我不确定如何,但如果这是最好的我可以看一下方式。)

1 个答案:

答案 0 :(得分:2)

嗯,这是我的两分钱。

  1. 最好创建单独的模式模型,然后根据需要注入模型。
  2. 例如 如果我有一个博客模式如下:

    before_save :update_role
    
    def update_role
      if self.card_amount >= 100
        self.role = "buyer"
      end
    end
    

    请注意,作者指的是 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

    在User和Blogspot中正在引用的已创建属性

    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);
    

    如果您想根据用户类型限制访问,则必须编写自定义验证,例如我们为电子邮件编写的用户架构:

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

    然后根据您所做的任何验证添加if-else。

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

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

    希望这有帮助! :)