How would I be able to structure a one to many relationship with document embedding or document referencing in meteor? I am using the simpleschema package and require to save an array of objects within a field.
So for example I have a invoice and I want to attached the individual products from the order.
So invoice -> productIds -> product data is the mapping. What do I set the field type to in simpleschema, can anyone provide a small example so I can get my head around this. I have read a lot that 1:n modelling is possible in Mongo and meteor although there are the composite publish package that can help retrieve children. The only part of the puzzle iām missing is how actually to legitimately insert (as in embed or reference) multiple objects to a document
Thanks in advance for any help on this
Iāve been studying the telescope source and see they achieve it via using _.pluck and a simple schema as so
/**
An array containing posts downvotes
*/
downvotedPosts: {
type: [Telescope.schemas.votes],
Insertion is done via a $addToSet
How would I use $addToSet with a autoform insert form; so that I could store embedded document ids to link a one to many relation in my data model?
I have this on my project, it basically works like this:
const LineItem = new SimpleSchema({
'productId': {
type: String,
allowedValues() {
return Products.find().map(s => s._id);
}
},
'quantity': {
type: Number,
defaultValue: 1,
min: 1
}
});
Orders.attachSchema(new SimpleSchema({
'products': { type: [Object] },
'products.$': { type: LineItem },
'subtotal': {
type: Number,
decimal: true,
autoValue() {
const products = this.field('products');
if (products.isSet && this.operator === '$set') {
return products.value.map(product => ({
price: Products.findOne(product).price,
quantity: product.quantity
})).reduce((memo, current) => {
return memo + (current.price * current.quantity);
}, 0);
}
}
}
}))
1 Like
ahhhhhhhh ok man thank you very very much!!
No matter how I configure the schema, with blackbox or not I always get the following errors:
SimpleSchema.clean: filtered out value that would have affected key "orders", which is not allowed by the schema
simple-schema.js:737 SimpleSchema.clean: filtered out value that would have affected key "orders.$", which is not allowed by the schema
collection2.js:374 Uncaught Error: After filtering out keys not in the schema, your object is now empty
I really cannot get it, Iāve read alot of other meteor applications sources and it seems they all use the type and object configuration as below:
@purchaseOrders = new Meteor.Collection('purchaseOrders');
Schemas.purchaseOrders = new SimpleSchema
message:
type: String
label: "Extra message or instructions"
optional: true
autoform:
afFieldInput:
type: "textarea"
rows: 4
purchaseStatus:
type: String
optional: true
orders:
type: Object
optional: true
"orders.$":
type: Object
"orders.$.productId":
type: String
"orders.$.quantity":
type: Number
min: 1
"orders.$.title":
type: String
"orders.$.supplierEmail":
type: String
"orders.$.owner":
type: String
No matter how I try to configure this collection I cannot seem to insert to it, very strange indeed.
Any ideas why I cannot save to the collection and get these errors? I also am using a before hook to set the variable
AutoForm.hooks
confirmPurchaseOrder:
before: insert: (doc,template) ->
doc.orders = Orders.find({}).fetch()
console.log doc.orders
return doc
onSubmit: (insertDoc, updateDoc, currentDoc) ->
console.log 'purchase form submitted'
onError: (name, error, template) ->
console.log name + ' error:', error
In the console I can see the doc.orders is set to the document returned. But I cannot save it.
I thought it was maybe this error (https://github.com/aldeed/meteor-autoform/issues/663) so I tried using the JSON.stringify but I still get the same error from SimpleSchema.clean
Are you using a quickform or an autoform? And if it is an autoform, can you paste in your form code please.
@serkandurusoy sure, Iām doing this inside a modal
<div class="modal-body">
<p>
<ul class="list-group">
{{#each orders}}
{{> orderItem}}
{{/each}}
</ul>
{{#autoForm collection="PurchaseOrders" type="insert" id="confirmPurchaseOrder"}}
{{> afQuickField name="orders" type="hidden" value=orders}}
{{> afQuickField name="message" rows=4 type="textarea" style="width: 100%;"}}
<button type="submit" class="btn btn-success" id="confirmOrderFinal">Confirm Order</button>
{{/autoForm}}
</p>
</div>`
@tomtom87 the problem here is, your schema expects the orders array to be filled within the form itself but since it is hidden, it is not validated.
You can either prefill the values on form creation with autoValue
or, create a single āorderMessageā schema that takes the message input only and attaches the order details later on, passing them on to the target collection.
@serkandurusoy ok I think I got it, by any chance to you have a example of populating the autoValue
with content inside of the autoForm context like we have it here.
I couldnāt figure out how to get that working before inside the schema.
you provide a doc
attribute to the autoform containing the initial values of your fields
<AutoForm doc=orders ....../>
such that orders
is a helper on the containing template and returns Orders.find({}).fetch()
ahh ok I will try this and get back to you
1 Like