meteormeteor-helpermeteor-collections

Meteor collections: how to connect to different collections referring to each other?


I have two collections:

Contracts = new Mongo.Collection('contracts');
Reminders = new Mongo.Collection('reminders');

These are structured in the database more or less like this:

Contracts:

{
  "id": "4432234",
  "contract": "C-42432432",
  "description": "Description of contract",
  "counterpart": "Company name",
  "status": "awarded"
},
etc.

Reminders:

{
  "name": "Contract expiring",
  "type": "expiring",
  "contract": "C-42432432",
  "reminderDate": "2015-06-01",
  "urgency": 3
},
etc.

The "contract"-name here are referring to a "contract"-name in the contract-collection. We can ha multiple reminders connected to the same contract. Therefore I want them in two different collections.

To get the contract-data I use:

<template name="example">
{{#each contracts}}
    {{description}}
{{/each}}
</template>

corresponding js:

Template.example.helpers({
  contracts: function() {
    return Contracts.find();
  }
});

This works ok and the result in this instance is Description of contract.

But what do I do if I want to display the reminder-collection and get the corresponding data from the Contract-collection? In other words: I want to loop the reminder-collection and get the same output.

<template name="notworking">
{{#each reminder}}
    {{description}}
    <!-- Here I want the description from the Contract-collection -->
{{/each}}
</template>

corresponding js:

Template.notworking.helpers({
  reminder: function() {
    //?
  }
});

Solution

  • You might be better off using Contracts._id to refer to a contract from the Reminders collection that way if the contract name and description change at some point you won't need to update all the related reminders.

    Contract:

    {
      "_id": "tPN5jopkzLDbGypBu",
      "contract": "C-42432432",
      "description": "Description of contract",
      "counterpart": "Company name",
      "status": "awarded"
    },
    

    Reminder:

    {
      "name": "Contract expiring",
      "type": "expiring",
      "contractId": "tPN5jopkzLDbGypBu",
      "reminderDate": "2015-06-01",
      "urgency": 3
    },
    

    Then if you want to list reminders and show related contract information you'd have:

    HTML:

    <template name="remindersList>
    {{#each reminder}}
      Date: {{reminderDate}} Urgency: {{urgency}}
      {{#with relatedContract}}
        Description: {{description}} Counterpart: {{counterpart}} Status: {{status}}
      {{/with}}
    {{/each}}
    </template>
    

    JS:

    Template.remindersList.helpers({
      reminder: function(){
        return Reminders.find(); // or whatever query you need to run
      },
      relatedContract: function(){
        return Contracts.findOne({_id: this.contractId}); // 'this' will be the Reminder document
      }
    });
    

    OR - if you want to keep your denormalized schema, then the relatedContract function would simply need to return Contracts.findOne({contract: this.contract})