Meteor collections: how to connect to different collections by referencing each other?

I have two collections:

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

      

They are structured in the database like this:

Contracts:

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

      

Memo:

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

      

Here, the term "contract" refers to "contract" -name in an assembly of contracts. We can use multiple reminders associated with the same contract. So I want them to be in two different collections.

To get the contract details I use:

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

      

matches js:

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

      

This works fine and the result is equal in this case Description of contract

.

But what should I do if I want to display the collection of reminders and get the relevant data from the Contract? In other words: I want to compose a collection of reminders and get the same result.

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

      

matches js:

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

      

+3


source to share


3 answers


You might be better off using Contracts._id

to denote a contract from a collection Reminders

in this way, if the name and description of the contract changes at some point, you won't need to update all relevant 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 relevant contract information, you would 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 wanted to keep your denormalized schema, then the function relatedContract

would simply have to returnContracts.findOne({contract: this.contract})

+1


source


I assume you need to iterate over each reminder inside a loop, iterating over each contract:

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

      

The current data context when evaluating reminders

will be currently under contract, so we can access its contract name with this.contract

.



As a result, you just need to return each dunning document with the same contract name.

Template.contracts.helpers({
  reminders: function(){
    return Reminders.find({
      contract: this.contract
    });
  }
});

      

+1


source


https://atmospherejs.com/reywood/publish-composite

This package provides a flexible way to publish a set of related documents from different collections using a reactive join. Hope it helps.

+1


source







All Articles