Different schema validations for one collection and value matching (Blaze)


#1

Hey,

I have the following example for Schema validation and inserting objects into Mongo Collections which is based on a simplified Master’s To-do’s app from the Meteor Guide:

export const Todos = new TodosCollection('todos');

Todos.schema = new SimpleSchema({
  _id: {
    type: String,
  },
  text: {
    type: String,
  },
  type: {
    type: String,
  },
});

Todos.attachSchema(Todos.schema);

The validation is done in methods.js applying a ValidationMethod on the collection’s insert method as follows:

  name: 'todos.insert',
  validate: Todos.simpleSchema().pick(['text', 'type']).validator(),
  run({ text, type }) {
    Todos.insert(todo);
  },
});

Now I want to add the following logic:

In my To-do’s collection, I want to have two different types of To-do items which I can add dependant on which button was pressed or which form was filled. Basically the items will differ as follows:

  • To-do item1:
    – the field “type” can only have either of the values: “A” or “B” or “C”
  • To-do item2:
    – the field “type” can only have either of the values: “B” or “C” or “D”
    – can have additional fields that are needed to be checked against, i.e. “someOtherField1”, “someOtherField2” to be of String value
  1. Should the logic to distinguish between the String values simply be done inside the run method, based on which type of to-do item to insert was triggered, or does the package support something like ‘value: Match.oneOf (“A”, “B”, “C”),’ with which I could work with?
  2. Should I add a second insert method for the second list as the fields to be checked against also differ, or is it possible to add the logic within one insert method, i.e. passing values to the method to distuingish between type1 or type2?

Thanks in advance!


#2

You should find the answer in aldeed:collection-2 where it talks about attaching multiple schemas to a collection.

Here is a very simple example

Schemas = {};
BaseSchema = {
   type: {
     type: String,
     allowedValues: ['simple','variant'],
     autoform: {
       type: 'hidden'
     }
   },
   title: {
       type: String,
       label: "Title",
       max: 200
   },
};
Schemas.Simple = new SimpleSchema(_.extend(BaseSchema,
{
   simpleField: {
       type: Date,
       label: "Simple Date",
   },
}
));
Schemas.Variant = new SimpleSchema(_.extend(BaseSchema,
{
   variantField: {
       type: Date,
       label: "Variant Date",
   },
}
));

Collection.attachSchema( Schemas.Simple, {selector: {type: 'simple'}} );
Collection.attachSchema( Schemas.Variant, {selector: {type: 'variant'}} );

Then you can use autoform like this

<template name="collectionInsert">
  {{>quickForm collection=Collection doc=doc id="insertPageForm" type="insert"}}
</template>

And you provide doc via a helper

Session.setDefault('type','simple');
Template.collectionInsert.helpers({
 doc(){
  // all autoform needs is the type so it can decide which schema to use
  return { type: Session.get('type') }
 }
});