Skip to content

Instantly share code, notes, and snippets.

@marshyon
Created October 1, 2015 18:56
Show Gist options
  • Save marshyon/88b0d665a04aff398fa9 to your computer and use it in GitHub Desktop.
Save marshyon/88b0d665a04aff398fa9 to your computer and use it in GitHub Desktop.
Meteor - linking parent / child ( posts / comments ) collections
<head>
<title>postsApp</title>
</head>
<body>
{{> posts}}
</body>
<template name="posts">
<ul>
{{#each posts}}
<li>{{title}} - [{{author}}]
<ul class="comments">
{{#each comments}}
{{> commentItem}}
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</template>
<template name="commentItem">
<li>
<h4>
<span class="author">{{author}}</span>
<span class="date">on {{submittedText}}</span>
</h4>
<p>{{body}}</p>
</li>
</template>
/*
this is lifted from 'Discovering Meteor' but lacks much of the
functionality of this example of 'adding comments'
is't just enough to demonstrate the listing of a series of
posts and for each post, a sub list of comments
this achieves a kind of 'join' of one collection to another where the
comments are 'linked' to the posts collection by the use of the '_id'
field from posts - attaching the 'child' comments to 'parent' posts
the trick is in the creation of the 'comments' collection which has the '_id'
field of the parent post within each collection item, like a key field in the
row of a table
*/
// declare collections on both client and server
Comments = new Mongo.Collection('comments');
Posts = new Mongo.Collection('posts');
if (Meteor.isClient) {
// within the 'posts' template, create helpers to return data from the two
// collections 'Posts' and 'Comments'
// - !! note the use of 'this._id' in the 'comments helper - this works
// in the context that this is used in, from within an 'each' block
// that iterates over the entries found in the 'Posts' collection
// thus 'inheriting' the '_id' of the current post - using this as
// a key in the 'comments' collection to pull out just the comments
// attached this 'this' post
Template.posts.helpers({
'posts': function(){
return Posts.find();
},
comments: function() {
return Comments.find({postId: this._id});
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
/*
populate an empty set of mongo db collections
with test data
for this to work a default meteor app needs user
authentication packages installed -
# meteor add accounts-base
# meteor add accounts-password
if we need to force the re-creation of this 'fixture' data, we can stop
meteor and 'reset' ( clear down ) the meteor db :
# meteor reset
*/
if (Posts.find().count() === 0) {
var now = new Date().getTime();
// create two users
var tomId = Meteor.users.insert({
profile: { name: 'Tom Coleman' }
});
var tom = Meteor.users.findOne(tomId);
var sachaId = Meteor.users.insert({
profile: { name: 'Sacha Greif' }
});
var sacha = Meteor.users.findOne(sachaId);
var telescopeId = Posts.insert({
title: 'Introducing Telescope',
userId: sacha._id,
author: sacha.profile.name,
url: 'http://sachagreif.com/introducing-telescope/',
submitted: new Date(now - 7 * 3600 * 1000)
});
Comments.insert({
postId: telescopeId,
userId: tom._id,
author: tom.profile.name,
submitted: new Date(now - 5 * 3600 * 1000),
body: 'Interesting project Sacha, can I get involved?'
});
Comments.insert({
postId: telescopeId,
userId: sacha._id,
author: sacha.profile.name,
submitted: new Date(now - 3 * 3600 * 1000),
body: 'You sure can Tom!'
});
Posts.insert({
title: 'Meteor',
userId: tom._id,
author: tom.profile.name,
url: 'http://meteor.com',
submitted: new Date(now - 10 * 3600 * 1000)
});
Posts.insert({
title: 'The Meteor Book',
userId: tom._id,
author: tom.profile.name,
url: 'http://themeteorbook.com',
submitted: new Date(now - 12 * 3600 * 1000)
});
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment