【问题标题】:Mongo user document structure with three user types具有三种用户类型的 Mongo 用户文档结构
【发布时间】:2015-12-21 14:41:32
【问题描述】:

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

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

这是我迄今为止提出的 - 一个需要所有基本信息的单一用户模型,但还设置了架构以允许学生需要包含的其他信息。然后,如果要保存的用户没有“学生”角色,我还设置了一个预保存挂钩以删除“学生信息”子文档:

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: 似乎如果我按照上述设置进行设置,我无法对子文档进行某些验证 - 我想要求学生填写子文档中的信息,但不是员工或管理员用户。当我将任何字段设置为必填时,即使不包含子文档本身,也会在不包含这些字段时引发错误。 (这是有道理的,但我不知道如何解决。也许自定义验证预保存也是如此?我以前从未写过,所以我不确定如何,但如果这是最好的,我可以查一下方式。)

【问题讨论】:

标签: node.js mongodb authentication express mongoose


【解决方案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);

以及在 User 和 Blogspot 中都被引用的 created 属性

// 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。所以,是的,自定义验证也预先保存。

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

希望这会有所帮助! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-22
    • 2011-10-17
    • 2017-02-20
    • 2014-04-24
    • 1970-01-01
    • 2015-02-27
    • 2018-09-17
    • 2013-03-18
    相关资源
    最近更新 更多