0

I have a publication based on server-side user permissions. I want it to be reactive to changes in these permissions.

// SERVER CODE
Meteor.publish("my_publication", function(parent_id) {
    //fetch our parent record and lookup this user's permissions
    var parent = ParentCollection.findOne({_id: parent_id});
    var myPermissionsList = parent.permissionsDict[this.userId];
    //use these permissions to make our query
    ChildCollection.find({parent_id: parent_id, permissions: {$in: myPermissionsList}})
}

// CLIENT CODE
Tracker.autorun(function () {
    Meteor.subscribe('my_publication', Session.get("my_parent_id"));
});

This properly returns all the elements of the "child" collection specified parent, as long as the parent says the user has at least one of the permissions in the child element's list. It does this without the user actually knowing what their permissions are, which is a requirement.

This behaves like one would expect in Meteor:

  • The subscription does automatically update if any of the returned ChildCollection elements are changed.
  • The subscription does automatically update if the client changes the "my_parent_id" Session variable, triggering the Tracker.autorun resubscribe.
  • The subscription does not automatically update if the permissions used to make the query (parent.permissionsDict[this.userId]) are changed.

We're looking for the best (highest performing) way to get an automatic update in the last case.

This article was a helpful, more detailed resource on the topic: https://www.discovermeteor.com/blog/reactive-joins-in-meteor/

My current understanding is that I need to utilize cursor.observeChanges() to react to changes in my permissions query. However, I am not sure how this fits into the rest of the Meteor publish/subscribe model--where would I call this, and how could the callback instruct Meteor to republish "my_publication"?

I believe https://atmospherejs.com/mrt/reactive-publish addresses this, but I feel like I should try to get a better grasp on core reactivity in meteor before turning to an external package. I also lack an understanding about the performance costs.

Any help would be greatly appreciated!

  • 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 Feb 13 '15 at 18:25

1 Answers1

0

You can use the reactive-publish package (I am one of authors):

Meteor.publish("my_publication", function(parent_id) {
    this.autorun(function (computation) {
        //fetch our parent record and lookup this user's permissions
        var parent = ParentCollection.findOne({_id: parent_id}, {fields: {permissionsDict: 1}});
        var myPermissionsList = parent.permissionsDict[this.userId];
        //use these permissions to make our query
        return ChildCollection.find({parent_id: parent._id, permissions: {$in: myPermissionsList}});
    });
}

It is important that you limit the fields you are interested in the parent document, otherwise autorun would rerun every time any field changes in the document, even if you do not care/use that field.

Mitar
  • 6,756
  • 5
  • 54
  • 86