nacho
nacho

Reputation: 651

Mongoose - Validate ObjectID related document

I need to validate as required a field "product" in Model Event. Product is ObjectID reference to Product Model.

I tried with this 2 approaches, but it is not validating

 product: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Product',
      required: true
    }]
  },



product: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Product',
      required: function () {
        return this.product.length > 0
      },
    }]
  },

The Event is being created anyway, and when I add no products, field product is an empty array.

Any idea how can I validate it?

Models:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Product = require('../models/Product');

const moment = require('moment');


const EventSchema = new Schema({

  client: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Client'
    }]
  },

  product: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Product',
      required: true
    }]
  },

  date: {
    type: Date,
    maxlength: 64,
    lowercase: true,
    trim: true
  },

  place: {
    type: String,
    maxlength: 1200,
    minlength: 1,
  },

  price: {
    type: Number
  },

  comment: {
    type: String,
    maxlength: 12000,
    minlength: 1,
  },

  status: {
    type: Number,
    min: 0,
    max: 1,
    default: 0,
    validate: {
      validator: Number.isInteger,
      message: '{VALUE} is not an integer value'
    }
  },
},
  {
    toObject: { virtuals: true },
    toJSON: { virtuals: true }
  },
  {
    timestamps: true
  },
);


const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Provider = require('./Provider')


const ProductSchema = new Schema({

  name: {
    type: String,
    maxlength: 64,
    minlength: 1,
    required: [true, 'Product name is required'],
  },

  brand: {
    type: String,
    maxlength: 64,
    minlength: 1,
  },

  description: {
    type: String,
    maxlength: 12000,
    min: 1,
  },

  comment: {
    type: String,
    maxlength: 12000,
    minlength: 1
  },

  state: {
    type: String,
    maxlength: 64,
    minlength: 0
  },

  disponible: {
    type: Boolean,
    default: true
  },

  price: {
    type: Number,
    default: 0,
    min: 0,
    max: 999999
  },

  provider: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Provider'
    }]
  },

  category: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Category'
    }]
  },

  event: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Event'
    }]
  },

  image: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Image'
    }]
  },
},
  {
    toObject: { virtuals: true },
    toJSON: { virtuals: true }
  },
  {
    timestamps: true
  });

Upvotes: 1

Views: 877

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17868

You can use custom validators feature of mongoose.

If the validator function returns undefined or a truthy value, validation succeeds. If it returns falsy (except undefined) or throws an error, validation fails.

    product: {
      type: [
        {
          type: Schema.Types.ObjectId,
          ref: "Product",
          required: true
        }
      ],
      validate: {
        validator: function(v) {
          return v !== null && v.length > 0;
        },
        message: props => "product is null or empty"
      }
    }

Now when you don't send product field, or send it empty array it will give validation error.

Upvotes: 2

Vinit Devani
Vinit Devani

Reputation: 54

 const notEmpty = function(users){
   if(users.length === 0){return false}
   else { return true }
 }

 const EventSchema = new Schema({
  product: {
    type: [{
      type: Schema.Types.ObjectId,
      ref: 'Product',
      required: true,
      validate: [notEmpty, 'Please add at least one']
    }]
  }
})

Upvotes: 0

Related Questions