Search code examples
meteormeteor-autoformmeteor-collection2simple-schema

Attaching multiple schemas to same collection using autoform and collection2


I have two forms and two schema that don't have anything in common. But I still need them to be stored in the same collection.

Eg.:

schema1 = new SimpleSchema({ field1, field2, field3 });
collection.attachSchema(schema1);

schema2 = new SimpleSchema({ fieldX, fieldY, fieldZ });
collection.attachSchema(schema2);

From Collection2 documentation it is understood that the above method will actually merge both the schema into a single big schema. This means that both form must have all fields belonging to both schema.

This means that I can't have an autoForm with just schema1 and another autoform with just schema2.

As per the documentation, I tried implementing replace: true - by which, the schema gets overwritten each time. ( At least this is how I understand it - they don't get merged into a big schema)

Eg:

schema1 = new SimpleSchema({ field1, field2, field3 });
collection.attachSchema(schema1, {replace: true});

schema2 = new SimpleSchema({ fieldX, fieldY, fieldZ });
collection.attachSchema(schema2 {replace: true});

The above still does not fix the issue and Somehow, the schemas still get merged. Meaning, I still get notified that FieldX is blank in autoform1 even though there is no provision for fieldX to be filled.

I Also tried the other approach where in you use variations.

Eg.:

schema1 = new SimpleSchema({ field1, field2, field3 });
collection.attachSchema(schema1, {selector: {type: 'forForm1'}});

schema2 = new SimpleSchema({ fieldX, fieldY, fieldZ });
collection.attachSchema(schema2, {selector: {type: 'forForm2'}});

When I implement the above, I get an autoform error saying that an argument to doc must be passed when dealing with multiple schema.

How exactly do I do this?

THe documentation specifically states :

Now both schemas are attached. When you insert a document where type: 'simple' in the document, it will validate against only the SimpleProductSchema. When you insert a document where type: 'variant' in the document, it will validate against only the VariantProductSchema.

I Don't know how I need to pass doc = ???? in the template. Could someone guide me?

This is my autoform template:

Form1:

{{#autoForm    collection = "pgTemplates"  type ="insert" doc= ???? id ="InsertForm1" }}
{{#each afFieldNames}}
{{> afQuickField name=this.name options = afOptionsFromSchema  }}
{{/each}}

Form2:

{{#autoForm    collection = "pgTemplates"  type ="insert" doc= ???? id ="InsertForm1" }}
{{#each afFieldNames}}
{{> afQuickField name=this.name options = afOptionsFromSchema  }}
{{/each}}

Solution

  • According to the documentation for autoform:

    doc: Required for an update form, and must have at least an _id property. Pass the current document object, retrieved with a call to findOne() for example. For an insert form, you can also use this attribute to pass an object that has default form values set (the same effect as setting a value attribute on each field within the form).

    There is also another parameter schema that may be of use in this case:

    schema: Required if collection is not set. This schema will be used to generate and validate the form prior to submission, so you can specify this along with a collection if you want to use a schema that is slightly different from the one your collection uses. However, the final object will still have to pass validation against the collection schema. Set to one of the following:

    • The name of a helper function (no quotation marks) that returns an instance of SimpleSchema.
    • The name (in quotation marks) of a SimpleSchema instance that is in the window namespace.

    So you can try setting the schema parameter according to your specific schema in each case, and also try to pass the current document object in doc.

    I suppose the template would look like:

    Form1:

    {{#autoForm  collection = "pgTemplates"  schema="schema1"  type ="insert" doc=docObject id ="InsertForm1" }}
      {{#each afFieldNames}}
        {{> afQuickField name=this.name options = afOptionsFromSchema1  }}
      {{/each}}
    

    Form2:

    {{#autoForm  collection = "pgTemplates"  schema="schema2"  type ="insert" doc=docObject id ="InsertForm1" }}
      {{#each afFieldNames}}
        {{> afQuickField name=this.name options = afOptionsFromSchema2  }}
      {{/each}}
    

    In the above case, you will need to make sure that your schema instances are available properly in the window namespace

    Or you can have a helper function returning the specific instance, like:

    With helper:

    {{#autoForm  collection = "pgTemplates"  schema=getSchema1  type ="insert" doc=docObject id ="InsertForm1" }}
        {{#each afFieldNames}}
          {{> afQuickField name=this.name options = afOptionsFromSchema2  }}
        {{/each}}