fuzzybabybunny
fuzzybabybunny

Reputation: 5254

How to entirely skip validation in simple schema and allow incomplete documents to be stored?

I'm creating an order form and a schema defined for an Order (certain required fields such as address, customer info, items selected and their quantities, etc).

a. User visits site.

b. A unique ID is generated for their session as well as a timestamp.

var userSession = {
  _id: createId(),
  timestamp: new Date(),
};

var sessionId = userSession._id;

c. The userSession is placed in local storage.

storeInLocalStorage('blahblah', sessionObject);

d. An Order object is created with the sessionId as the only field so far.

var newOrder = {
  sessionId: sessionId;
};

e. Obviously at this point the Order object won't validate according to the schema so I can't store it in Mongo. BUT I still want to store it in Mongo so I can later retrieve incomplete orders, or orders in progress, using the sessionID generated on the user's initial visit.

This won't work because it fails validation:

Orders.insert(newOrder);

f. When a user revisits the site I want to be able to get the incomplete order from Mongo and resume:

var sessionId = getLocalStorage('blahblah')._id;
var incompleteOrder = Orders.findOne({'sessionId', sessionId});

So I'm not sure how to go about doing this while accomplishing these points.

I can make a field conditionally required using this here but that would mean 50+ fields would be conditionally required just for this scenario and that seems super cumbersome.

Upvotes: 2

Views: 1261

Answers (4)

Tobi
Tobi

Reputation: 1313

While this question is very old in the meantime there is a better solution. You probably use simple schema together with collection2. Collection2 has the ability to set multiple schemas based on a selector and then validate against the correct schema based on it.

https://github.com/Meteor-Community-Packages/meteor-collection2#attaching-multiple-schemas-to-the-same-collection

e.g. you could have a selector {state: 'finished'} and only apply the full schema to these documents while having another selctor, e.g. {state: 'in-progress'} for unfinished orders with a schema with optional fields.

Upvotes: 0

jmendiola
jmendiola

Reputation: 413

I think this particular case has been solved; but just in case, you can skip Simple Schemma validations by accessing MongoDB native API via Collection#rawCollection():

Orders.rawCollection().insert(newOrder);

Upvotes: 1

Michel Floyd
Michel Floyd

Reputation: 20227

Here's a variation on @JeremyK's answer: add an inProgress key to your order of type [Object]. This object would have no deeper validation. Keep your in progress order data in there until the order is final then copy/move all the relevant data into the permanent keys and remove the inProgress key. This would require that you make all the real keys optional of course. The advantage is that the object would maintain its primary key throughout the life cycle.

Upvotes: 1

JeremyK
JeremyK

Reputation: 3240

It sounds like you want to have your cake, and eat it too!

I think the best approach here would be keep your schema and validation on the Orders collection, but store incomplete orders elsewhere.
You could store them in another collection (with a more relaxed schema) if you want them on the server (possibly for enabling resume on another device for the logged in user) , or more simply in Local Storage, and still enable the resume previous order behaviour you are wanting.
Only write to the Orders collection when the order is complete (and passes validation).

Upvotes: 1

Related Questions