Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent field modification with Mongoose Schema

Is there any way to set a field with an "unmodifiable" setting (Such as type, required, etc.) when you define a new Mongoose Schema? This means that once a new document is created, this field can't be changed.

For example, something like this:

var userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unmodifiable: true
  }
})
like image 412
Dan Monero Avatar asked May 26 '18 15:05

Dan Monero


People also ask

What does __ V mean in Mongoose?

The __v field is called the version key. It describes the internal revision of a document. This __v field is used to track the revisions of a document. By default, its value is zero ( __v:0 ).

What does $Set do in Mongoose?

The $set operator replaces the value of a field with the specified value. The $set operator expression has the following form: { $set: { <field1>: <value1>, ... } } To specify a <field> in an embedded document or in an array, use dot notation.

What is the difference between id and _ID in Mongoose?

So, basically, the id getter returns a string representation of the document's _id (which is added to all MongoDB documents by default and have a default type of ObjectId ). Regarding what's better for referencing, that depends entirely on the context (i.e., do you want an ObjectId or a string ).

What does .save do Mongoose?

Mongoose | save() Function The save() function is used to save the document to the database. Using this function, new documents can be added to the database.


1 Answers

From version 5.6.0 of Mongoose, we can use immutable: true in schemas (exactly as the aforementioned answer on mongoose-immutable package). Typical use case is for timestamps, but in your case, with username it goes like this:

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    immutable: true
  }
});

If you try to update the field, modification will be ignored by Mongoose.


Going a little further than what have been asked by OP, now with Mongoose 5.7.0 we can conditionally set the immutable property.

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    immutable: doc => doc.role !== 'ADMIN'
  },
  role: {
    type: String,
    default: 'USER',
    enum: ['USER', 'MODERATOR', 'ADMIN'],
    immutable: true
  }
});

Sources: What's New in Mongoose 5.6.0: Immutable Properties and What's New in Mongoose 5.7: Conditional Immutability, Faster Document Arrays.

like image 182
sgy Avatar answered Nov 15 '22 20:11

sgy