Edit your documents before sending without too much stress
MIT License
Edit your documents before sending without too much stress
NOTE: this package is now called cottz:publish-relations and is hosted on https://github.com/Goluis/cottz-publish-relations
$ meteor add cottz:publish
provides a number of methods to easily manipulate data using internally observe and observeChanges in the server
Assuming we have the following collections
// Authors
{
_id: 'someAuthorId',
name: 'Luis',
profile: 'someProfileId',
bio: 'I am a very good and happy author',
interests: ['writing', 'reading', *others*]
}
// Reviews
{
_id: 'someReviewId',
authorId: 'someAuthorId',
book: 'meteor for pros',
text: 'this book is not better than mine'
}
// Books
{
_id: 'someBookId',
authorId: 'someAuthorId',
name: 'meteor for dummies'
}
// Comments
{
_id: 'someCommentId',
bookId: 'someBookId',
text: 'This book is better than meteor for pros :O'
}
I want publish the autor with his books
Meteor.publish('author', function (authorId) {
Publish.relations(this, Authors.find(authorId), function (id, doc) {
this.cursor(Books.find({authorId: id})).publish();
});
return this.ready();
});
and comments of the books
Meteor.publish('author', function (authorId) {
Publish.relations(this, Authors.find(authorId), function (id, doc) {
this.cursor(Books.find({authorId: id})).publish(function (id, doc) {
this.cursor(Comments.find({bookId: id})).publish();
});
});
return this.ready();
});
I also want to bring the profile of the author but within the author not apart
Meteor.publish('author', function (authorId) {
Publish.relations(this, Authors.find(authorId), function (id, doc) {
this.cursor(Books.find({authorId: id})).publish(function (id, doc) {
this.cursor(Comments.find({bookId: id})).publish();
});
doc.profile = this.cursor(Profiles.find(doc.profile))
.changeParentDoc(function (profileId, profile) {
return profile;
});
});
return this.ready();
});
I want to include the reviews of the author within this
Meteor.publish('author', function (authorId) {
Publish.relations(this, Authors.find(authorId), function (id, doc) {
this.cursor(Books.find({authorId: id})).publish(function (id, doc) {
this.cursor(Comments.find({bookId: id})).publish();
});
doc.profile = this.cursor(Profiles.find(doc.profile))
.changeParentDoc(function (profileId, profile) {
return profile;
});
doc.reviews = this.cursor(Reviews.find({authorId: id}))
.group(function (doc, index) {
return doc;
}, 'reviews');
});
return this.ready();
});
// doc.reviews = [{data}, {data}]
To finish I want to show only some interests of the author
Meteor.publish('author', function (authorId) {
Publish.relations(this, Authors.find(authorId), function (id, doc) {
this.cursor(Books.find({authorId: id})).publish(function (id, doc) {
this.cursor(Comments.find({bookId: id})).publish();
});
doc.profile = this.cursor(Profiles.find(doc.profile))
.changeParentDoc(function (profileId, profile) {
return profile;
});
doc.reviews = this.cursor(Reviews.find({authorId: id}))
.group(function (doc, index) {
return doc;
}, 'reviews');
doc.interests = this.paginate({interests: doc.interests}, 5);
});
return this.ready();
});
// doc.reviews = [{data}, {data}]
// Client
// skip 5 interest and show the next 5
Meteor.call('changePagination', 'authorId', 'interests', 5);
publishes a cursor, collectionName
is not required
observe or observe changes in a cursor without sending anything to the client. callbacks are the same as those used by meteor
{cursor: Authors.find(), name: 'authors'}
or just a cursor and the name will be the default name of the cursorid
, doc
, changed
)after starting a Publish.relations you can use the methods in this
within the callback
allow you to use cursor methods in the cursor
collection
is the collection where the cursor will be sent. if not sent, is the default cursor collection namepage within an array without re run the publication or callback
id
and field
. skip is the number of values to skipafter creating an instance of this.cursor
can use the following methods
publishes a cursor
observe or observe changes in the cursor without sending anything to the client. callbacks are the same as those used by meteor
designed to change something in the document with the return of the callbacks
.
added``changed``removed
or a function that executes when it is added and changedreturns an array of elements with all documents in the cursor. When there is a change it will update the element change in the resulting array and send it back to the document
doc
, atIndex
) when is added and (doc
, atIndex
, oldDoc
) when is changed{sort: array, sortField: '_id'}
implements changes based on the position within the sort
. sort
is an array of values and sortField
is the field of the document where they are, by default is the _idgroup
use observe with absolute position information (addedAt, changedAt, removedAt), if possible try using only publish
to maintain performanceI keep all cursors by name and if within the same instance is called at the same cursor will stop the first and second replace him
Meteor.publish('movie', function (directorId) {
Publish.relations(this, Movies.find({director: directorId}), function (id, doc) {
this.cursor(Meteor.users.find({_id: directorId})).publish(); // this cursor will not receive updates
this.cursor(Meteor.users.find({_id: doc.producerId})).publish();
});
return this.ready();
});
you can avoid this problem in the following two ways
Meteor.publish('movie', function (directorId) {
Publish.relations(this, Movies.find({director: directorId}), function (id, doc) {
this.cursor(Meteor.users.find({_id: directorId}).publish(function () {
this.cursor(Meteor.users.find({_id: doc.producerId})).publish();
});
});
return this.ready();
});
this is much better than the first way
Meteor.publish('movie', function (directorId) {
Publish.relations(this, Movies.find({director: directorId}), function (id, doc) {
this.cursor(Meteor.users.find({_id: directorId}), 'users').publish(); // users is the default of Meteor.users
this.cursor(Meteor.users.find({_id: doc.producerId}), 'producers').publish();
});
return this.ready();
});