Skip to content

Instantly share code, notes, and snippets.

@dburles
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dburles/8828501 to your computer and use it in GitHub Desktop.
Save dburles/8828501 to your computer and use it in GitHub Desktop.
if (Meteor.isClient) {
Meteor.subscribeReactive = function(name) {
var keyValues = {};
var mapper = Reactive[name].mapper;
var relations = Reactive[name].relations;
if (! mapper.key)
mapper.key = '_id';
Deps.autorun(function() {
// pass through object containing
// the default _id's
// any foreignKey values
// on each
keyValues[mapper.key] = mapper.cursor().map(function(doc) { return doc[mapper.key]; });
_.each(relations, function(relation) {
if (relation.foreignKey !== mapper.key)
keyValues[relation.foreignKey] = mapper.cursor().map(function(doc) { return doc[relation.foreignKey]; });
});
console.log('subscribing with ', keyValues);
Meteor.subscribe(name, keyValues);
// Meteor.subscribe(name, mapper.cursor().map(function(doc) { return doc[mapper.key]; }));
});
};
}
// TODO
// get rid of undefined values from maps
if (Meteor.isServer) {
Meteor.publishReactive = function(name) {
Meteor.publish(name, function(keyValues) {
var mapper = Reactive[name].mapper;
// by default the mapper will always pass through array of _id's
if (! mapper.key)
mapper.key = '_id';
console.log(Reactive[name].mapper);
console.log(keyValues);
// on first subscribe, server resolves the relationships
if (keyValues[mapper.key].length === 0)
keyValues[mapper.key] = mapper.cursor().map(function(doc) { return doc[mapper.key]; });
var relations = Reactive[name].relations;
var relationCursors = [];
_.each(relations, function(relation) {
// on first subscribe, server resolves the relationships
if (keyValues[relation.foreignKey].length === 0 && relation.foreignKey !== mapper.key)
keyValues[relation.foreignKey] = mapper.cursor().map(function(doc) { return doc[relation.foreignKey]; });
// build query
if (! relation.key)
relation.key = '_id';
if (! relation.query)
relation.query = {};
if (! relation.options)
relation.options = {};
// manually pass in things to join on
if (relation.in) {
relation.query[relation.in.key] = { $in: relation.in.values() };
} else {
if (relation.foreignKey !== mapper.key)
relation.query[relation.key] = { $in: keyValues[relation.foreignKey] };
else
relation.query[relation.key] = { $in: keyValues[mapper.key] };
}
console.log(relation.query, relation.options);
// console.log(relation.collection().find(query, options).fetch());
relationCursors.push(relation.collection().find(relation.query, relation.options));
});
return [
mapper.cursor(),
// TODO
// publish more cursors
].concat(relationCursors);
});
};
}
Reactive = {
feed: {
mapper: {
cursor: function() { return Feeds.find({}, { limit: 20, sort: { createdAt: -1 }}); },
},
relations: [{
collection: function() { return Meteor.users; },
foreignKey: 'userId'
}, {
collection: function() { return Events; },
// key: specify the name of the field on this collection?
foreignKey: 'eventId'
}]
}
};
Reactive = {
topPostsWithTopComments: {
// The collection that we want to map _id's from
mapper: {
// How to pass different options to the mapper cursor between server and client?
cursor: function() { return Posts.find({}, {sort: {score: -1}, limit: 30}); }
},
// The collection where `mapper.key $in mapper.cursor().map( ... )`
relation: {
key: 'postId',
collection: function() { return Comments; },
in: {
key: '_id', // if we don't pass this, assume _id?
values: function() {
var topPostsCursor = Reactive.topPostsWithTopComments.mapper.cursor();
var postIds = topPostsCursor.map(function(p) { return p._id; });
var commentIds = _.map(postIds, function(postId) {
var comment = Comments.findOne({postId: postId}, {sort: {score: -1}});
return comment._id;
});
return commentIds;
}
}
// filter: {},
// options: {sort: {score: -1}, limit: 1}
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment