[SOLVED] Need help with relations between collections


#1

Hey guys.
Right now I’m working on an e-commerce app, I use Meteor 1.3.
For now I’m stucked on defining relations between two collections. I have two of them, let’s say Products and Customers, I use meteor-collection-helpers to manage this task and for now my code looks like this:

Products.js
import {Mongo} from ‘meteor/mongo’;
import {Customers} from ‘./customers.js’;

export const Products = new Mongo.Collection('products');

Products.helpers({
    getName() {
        return this.productName;
    },
    getId() {
        return this._id;
    },
    customers() {
        return Customers.findOne(this.customerId);
    }
});

Customers.js
import {Mongo} from ‘meteor/mongo’;
import {Products} from ‘./products.js’;

export const Customers = new Mongo.Collection('customers');

Customers.helpers({
    tours() {
        return Products.find({customerId: this._id});
    }
});

And this is the method to insert a new customer into Customers collection:
Customers.insert({ name, phone, email, productId: Products.findOne().getId(), product: Products.findOne().getName(), createdAt: new Date(), });

RIght after order form is submitted I get a new document but the problem is I can correctly apply insert method for only first document, whe I try submitting order form for the second order this document still grabs the name and id of the first document, so for now it makes no sense to use this form :smiley:
I actually changed the code a lot while googling but ended up with nothing and saved pieces I showed you because at least it works even for the only first product.
I guess I did something wrong while defining productId method but can’t get it, so I hope to find help here. Any suggestions will be warmly welcomed and if I will find out my mistake before any posts in this topic I 'd definetely share it.


#2

Looks like you should be specifying a specific product ID here;

productId: Products.findOne().getId(),

By writing something like

productId: pid

Use an argument to pass this in from wherever they’re selecting the product from. Then use that same pid to get the name in the next part:

product: Products.findOne(pid).getName()

Right now you’re just grabbing the same first product in the collection every time you insert a new customer. Hope this helps!


#3

Hey, sorry for late response, didn’t have an opportunity to work on my problem.
Yes, I understand that I should somehow pass product’s id, but I just don’t really know how to do it and it got me stucked :cry:
For example, as you can see I use a helper to retrieve id but it doesn’t work, also I tried to return another value, like const productName = Products.find({pid: product._id}) but it makes no difference :frowning:


#4

Aight folks calm down, seems like I’m on my way to solve this issue. Hope to post my solution later this day.


#5

Alright, finally I found a solution. As @bandit said, I didn’t specified which ID I need to grab so insert grabs only the first document in collection. By the way I did it without any additional package, the final query looks like this: productName: Products.findOne(this.props.product._id).productName


#6

Hey guys, another quick update for anyone wondering how to make such relations possible through methods. As you can see at first I solved this issue by passing the right ID into productName query when inserting a document, insecure package was active though. When it comes to Meteor methods the final solution looks like this:
Customers.js
declaring collection and methods

'customers.insert'(name, phone, email, pid) {
    Customers.insert({
        name,
        phone,
        email,
        product: pid,
        createdAt: new Date()
    });
},

As you can see a have another variable pid which stands for product ID, I use this variable in my component to get this product’s name like this:

let pid = Products.findOne(this.props.product._id).productName;
    
Meteor.call('customers.insert', name, phone, email, pid);

So it just works!