Reputation: 4494
I am using meteor-roles package for adding roles functionality to the app. Now I'm trying to filter a subscription of product based on the user of having a role to see that product category.
I thought I can use mongo $where in meteor but I can specify the $where function only as serialized string which does not have access to the roles package.
Example of adding a user to a role for viewing specific category.
Roles.addUsersToRoles(userIdA, 'view-product-category', 'product-category-a');
Current code that does not work. userId
does not exists when the function get deserialized in mongo engine.
Meteor.publish('products', function () {
let userId = this.userId;
let query = {
$where: function () {
return Roles.userIsInRole(userId, 'view-product-category', `product-catogory-${this.category}`);
}.toString();
};
return Products.find(query);
});
How does one filter a collection based on values different collection, which what I'm trying to do here ?
Current direction is to serialize the function myself and put the values needed there. I'm looking to know if there is more general and robust way of doing this kind of acl access filtering on subscriptions.
Upvotes: 0
Views: 225
Reputation: 20246
$where
is unindexed and slow. I believe what you're trying to do is filter products that have a category key. The user has a number of roles that allow them to view various categories.
You want to setup your query as:
Products.find({category: {$in: userCategories}});
Fortunately, the roles api has a getRolesForUser
function that will get all the user's roles for you.
So do:
const myRoles = getRolesForUser(Meteor.userId());
const userCategories = f(myRoles); // whatever you need to do to format these roles as categories
Products.find({category: {$in: userCategories}});
I'm not clear on how your role groups play into this hence the pseudo-answer. But basically you want userCategories
to be an array of the category names the user has access to. This query will be fast as long as the category
field is indexed.
Upvotes: 1