我正在 Express 中使用 Mongoose 设置 Mongo 数据库,并尝试决定如何对用户进行建模。我以前从未在 MEAN 堆栈中对多个用户进行建模,并且认为我应该寻求一些最佳实践 - 我是一名讲师,需要能够教授我的学生最佳实践。我没能找到很多东西,但也许我正在寻找错误的东西。
该应用将有 3 种用户类型:学生
、员工
和管理员
。每种用户类型都需要一些相同的基本信息 - 电子邮件、密码、名字和姓氏、电话等。如果用户是学生
,他们将需要提供其他信息,例如高中姓名、年级、年龄、性别等,最好是必需的。
这就是我到目前为止所想出的 - 一个单一用户模型,需要所有基本信息,但还设置了架构以允许学生需要包含的附加信息。然后,如果要保存的用户没有“学生”角色,我还设置了一个预保存 Hook 来删除“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
属性与上述内容轻松检查设置。但是,如果最好针对不同的用户类型使用单独的模型/集合,那么我如何检查尝试访问 protected 资源的“员工”还是“学生”?
问题3:如果我按照上面的设置进行设置,我似乎无法对子文档进行某些验证 - 我想要求学生填写子文档中的信息,但不是员工或管理员用户。当我将任何字段设置为必填时,如果不包含这些字段,它会引发错误,即使子文档本身不是必需的。 (这是有道理的,但我不知道如何解决。也许自定义验证预保存也是如此?我以前从未写过,所以我不确定如何,但我可以查一下,如果这是最好的方式。)
最佳答案
好吧,这是我的两分钱。
- 您最好创建单独的架构模型,然后根据需要注入(inject)模型。
例如 如果我有一个博客架构如下:
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。所以,是的,自定义验证也会预先保存。
由于您是一名讲师,我更愿意只指出所使用的实践,而不是详细说明您的具体问题。
希望这有帮助! :)
关于node.js - 具有三种用户类型的 Mongo 用户文档结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34398246/