2

I'm working on a Meteor app that uses several Collections that reference each other in a tree-style organization. However, they're all represented as flat Collections in my database structure. For example I have a top-level Cars Collection, a Parts Collection and a Sellers Collection that looks like this (pseudo-code):

Cars {
   _id:
   make:
   model:
   year:
   etc...
}

Parts {
   _id:
   carId: Cars._id
   type:
   desc:
   etc...
}

Seller {
   _id:
   partId: Parts._id
   location:
   name:
   etc...
}

So the way they reference each other in the tree would look like this:

Car
 |
 ---->  Part
 |       |
 |       ----> Seller
 |       |
 |       ----> Seller
 |       |
 |       ----> Seller
 |
 ---->  Part
         |
         ----> Seller
         |
         ----> Etc...

The problem I'm having is I use several top level publications where I pass the Car._id and want to see all the Sellers that sell Parts for that Car. So in my route I have a Subscribe that looks like this:

waitOn: function() {
   return Meteor.subscribe('allSellersByCar', this.params._id);
}

So to return all the Sellers from a Car._id I fetch all the Parts that match the Car._id and then use Underscore to _.pluck() the Part._id and find all the Sellers that match the array of Part._id:

Meteor.publish('allSellersByCar', function(carId) {
   var parts = Parts.find({carId: carId}).fetch();
   return Sellers.find({partId: {$in: _.pluck(parts, "_id")}});
});

This method works fine and returns all the Sellers correctly. The problem is this method will ONLY reatively return Sellers as they get added to EXISTING Parts and the Template will live update as expected, BUT it will not return any Sellers that get added to any NEW Parts that get added to the Car object. So it seems it only reactively updates the last line of the query. The entire query doesn't rerun when a new Part gets added. But if you refresh the page (and hence the route), the query reruns and everything gets returned correctly.

I have multiple publications like this in my app, some of which have several more "middle-man" fetches before returning. I'm not sure how to fix this or what the problem is. Am I going about my pub/subs wrong? Should I de-normalize the references more and add a carId to each Seller so I can just do the query directly on the Seller Collection in one line and not have to go through the Parts fetch?

evolross
  • 533
  • 1
  • 5
  • 15
  • possible duplicate of [Meteor.publish: publish collection which depends on other collection](http://stackoverflow.com/questions/26398952/meteor-publish-publish-collection-which-depends-on-other-collection) – David Weldon Nov 04 '14 at 20:28
  • The issue is that your publish function is not reactive. Specifically, your parts variable and the array of ids you create from it are not reactive data sources so the publish doesn't rerun them. There are a variety of strategies to make it reactive so I suggest the 'reactive joins' chapter of Discover Meteor to look at options to do this: https://www.discovermeteor.com/blog/reactive-joins-in-meteor/ – Jeremy S. Nov 04 '14 at 21:44
  • Ah yes. I read that article a while back and it was kind of lost on me until now. The article def helps, thank you. I think just a pinch of denormlization may go a long way for me. – evolross Nov 04 '14 at 22:53

0 Answers0