Reputation: 533
I have a template that displays documents from three different collections Cars
, CarPaints
, and CarPaintTypes
. I know I need all these upfront at the Router level. The template will show a Car
document, all the CarPaints
that reference that Car
, and all the CarPaintTypes
that reference the returned CarPaints
respectively (think nested list). The route to the template takes an id
from the URL that represents Car._id
.
Both the Cars
collection and CarPaints
collection make use of the Car._id
as a field (it's the native _id
of the Cars
collection and a field in the CarPaints
collection) so that's easy. However, the CarPaintTypes
uses the CarPaint._id
as a reference to what CarPaint
it belongs to.
So I have three publications:
Meteor.publish('car', function(carId) {
return Cars.find({_id: carId});
});
Meteor.publish('carPaints', function(carId) {
return CarPaints.find({carId: carId});
});
Meteor.publish('carPaintTypes', function(carPaintId) {
return CarPaintTypes.find({carPaintId: carPaintId});
});
My route looks like:
this.route('car', {
path: '/car/:_id',
waitOn: function() {
return [Meteor.subscribe('car', this.params._id),
Meteor.subscribe('carPaints', this.params._id)];
// Can't figure out how to subscribe to or publish
// the carPaintTypes using all the results of what gets
// returned by 'carPaints'
}
});
My question is CarPaintTypes
doesn't have the Car._id
as a field, just the CarPaint._id
to reference to a CarPaint
document. Where and how I do take the results of the subscription to carPaints
and pass each carPaint
document that's returned to a subscription to carPaintTypes
? Or is there a way to combine them all in the publication? Is it better to do it later on in my helpers? I figure since I know what I need at the route level, all the subscription calls should be in the route code.
Upvotes: 0
Views: 64
Reputation: 533
With Kuba Wyrobek's help, I figured it out. For what I was trying to achieve, the publish looks like this:
Meteor.publish('carThings', function(carId){
var carPaints = CarPaints.find({carId: carId}).fetch();
return [
Cars.find({_id: carId}),
CarPaints.find({carId: carId}),
CarPaintTypes.find({carPaintId: {$in: _.pluck(carPaints, "_id")}})
];
});
I didn't get that you could do manipulations inside your publication blocks. This is super cool and flexible. Thanks for your help.
Upvotes: 0
Reputation: 5273
You can grab all 3 cursors inside Meteor.publish
method and simply return them:
Meteor.publish('carThings', function(carId){
var carPaint = CarPaints.findOne({carId:carId});
return [
Cars.find({_id: carId}),
CarPaints.find({carId: carId}),
CarPaintTypes.find({carPaintId: carPaint._id});
]
})
On client:
this.route('car', {
path: '/car/:_id',
waitOn: function() {
return [Meteor.subscribe('carThings', this.params._id)]
}
}
Upvotes: 1