Let's say I have a Schema like this:
Schema({
username: String,
privilege: {
type: String,
enum: ["admin", "pro", "user", "guest"],
required: false,
default: "user"
},
tagType: { // A little badge that appears next to users' names on the site.
///???
}
});
For the tagType
, I would like to be able to define something like this if privilege
is admin
:
{
color: String,
image: String,
text: {
type: String,
required: true,
enum: ["I'm the highest rank", "I'm an admin", "Admin privileges are great"]
},
dateAdded: Date
}
Meanwhile, if privilege
is pro
:
{
color: String,
text: {
type: String,
required: false,
enum: ["This website is great", "I'm am a Pro user", "I get a nice tag!"],
default: "This website is great"
},
dateAdded: Date
}
Meanwhile, for all user
or guest
entries, no option should be allowed.
Is this sort of dynamic cross-checking possible? I have tried reading through the docs, but despite things that seem much more complex being in there, I couldn't find any way to achieve this.
You can implement this by using Discriminators
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
username: String,
privilege: {
type: String,
enum: ["admin", "pro", "user", "guest"],
required: false,
default: "user"
}
},
{ discriminatorKey: "privilege" }
);
const User = mongoose.model("User", userSchema);
User.discriminator(
"admin",
new Schema({
tagType: {
color: String,
image: String,
text: {
type: String,
required: true,
enum: ["I'm the highest rank","I'm an admin","Admin privileges are great"]
},
dateAdded: { type: Date, default: Date.now }
}
})
);
User.discriminator(
"pro",
new Schema({
tagType: {
color: String,
text: {
type: String,
required: false,
enum: ["This website is great","I'm am a Pro user","I get a nice tag!"],
default: "This website is great"
},
dateAdded: { type: Date, default: Date.now }
}
})
);
module.exports = User;
With this model and schema you can create a user with tagType it will be ignored.
Sample code to create user:
const User = require("../models/user");
router.post("/user", async (req, res) => {
let result = await User.create(req.body);
res.send(result);
});
Sample request body:
{
"username": "user 1",
"tagType": {
"color": "red",
"text": "I'm an admin"
}
}
Response:
{
"privilege": "user",
"_id": "5dfa07043a20814f80d60d6b",
"username": "user 1",
"__v": 0
}
Sample request to create an admin: (note that we added "privilege": "admin"
)
{
"username": "admin 1",
"privilege": "admin",
"tagType": {
"color": "red",
"text": "I'm an admin"
}
}
Response: (note that tagType is saved)
{
"_id": "5dfa07a63a20814f80d60d6d",
"privilege": "admin",
"username": "admin 1",
"tagType": {
"color": "red",
"text": "I'm an admin",
"dateAdded": "2019-12-18T11:04:06.461Z"
},
"__v": 0
}