-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How do you count based on user profile which is stored in a different collection? #71
Comments
I believe this is answered here. Let me know if it doesn't. |
Thanks for the response @boxofrox ! it didn't work :( I have an idea on how to solve this problem, which I filed an issue here on autoform and on Meteor forums here. Basically, I will add hooks after doc insert then insert an autoincrement |
The OP is a bit vague on details, so I may not understand what you're trying to achieve. Based on your forum question, I don't think it's necessary to add a count field to your documents. Provide an example of your Meteor.publish routine used to grab the user profile and publish the count, then I can give specific corrections. |
Thanks @boxofrox for looking into my problem. What I am trying to achieve is to count the documents of a user inserted into the collection. But the problem is, I have 3 different roles, admin, HQ and Branch. _Admin_ i can easily count the all the documents which is the expected behaviour mycollection.find().count(). _HQ_ (Company Headquarters) - count only the documents inserted by HQ and it's branches. _Branch_ (Company branch) - count only the documents inserted by branch. I already grab the users profile (company and branch) like this:
Here's publish function (for HQ):
My subscription:
Helpers
I don't know how do I inject the roles to limit the count based on user profile. Here's how I check for a user roles: var user = Meteor.users.findOne({"_id": this.userId},{fields:{profile: 1}}); |
Here's the user profile looks like:
|
Thanks for the details. Looks like you have few collections (Meteor.users, Roles, and Enrollments). If you require normalized data among your collection and rely on a join between Roles and Enrollments, then I'm not sure I have an answer. @tmeasday mentioned in another issue that coding server-side joins is best to avoid. If your joins and subsequent counts are client-side, then publish-counts isn't of much use. If you have no normalization policy--and it's my understanding that with MongoDB you should not--then we might consider including So your Enrollments document would look like: {
"company": "KRkwBeicgL5ayedGa",
"branch": "66DP8rYtrSGWtDFMK",
... other Enrollment fields
} Then your publish function might be: Meteor.publish("enrollmentsByAdmin", function (limit) {
Counts.publish(this, 'enrollments', Enrollments.find({}), {noReady: true});
if (limit) {
return Enrollments.find({});
} else {
return Enrollments.find({}, {limit: limit}) ;
}
});
Meteor.publish("enrollmentsByCompany", function(company, limit) {
Counts.publish(this, 'enrollments', Enrollments.find({company: company}), {noReady: true});
if (limit) {
return Enrollments.find({company: company});
} else {
return Enrollments.find({company: company}, {limit: limit}) ;
}
});
Meteor.publish("enrollmentsByBranch", function(branch, limit) {
Counts.publish(this, 'enrollment', Enrollments.find({branch: branch}), {noReady: true});
if (limit) {
return Enrollments.find({branch: branch});
} else {
return Enrollments.find({branch: branch}, {limit: limit}) ;
}
}); And your subscription logic will be: var user = Meteor.users.findOne({"_id": this.userId},{fields:{profile: 1}});
if (Roles.userHasRole(this.userId, "Admin"))
Meteor.subscribe("enrollmentsByAdmin", 5);
else if (Roles.userHasRole(this.userId, "HQ"))
Meteor.subscribe("enrollmentsByCompany", user.profile.company, 5);
else if (Roles.userHasRole(this.userId, "Branch"))
Meteor.subscribe("enrollmentsByBranch", user.profile.branch, 5);
console.log("enrollment count: ", Counts.get("enrollments")); Note: this code does not react to changes in a user's role. If a user is assigned Note: also, I assume a user only subscribes to one enrollment publishing, so all three counts use the Sorry the response took so long. I had to rewrite this post a few times as I grokked your code examples. |
Wow! Thanks @boxofrox for this! I don't have any normalization policy as i don't know how to normalized a collection. Yeah, on Enrollments i have this:
BTW, I am using orionjs as my admin. I will try this later at home as this is not my main job. I will let you know and hopefully close this issue 👍 |
The console log output is all 0 even on admin, so I've modified the admin publish to:
I've post an issue on nicolas lopez roles repo, he is the author of the package as well as orionjs here. I will wait for his comment if has something to do with his package. Thanks a lot again @boxofrox for helping me! |
FYI. You can move most of the processing to the server. Update your server-side publish routine to: function getEnrollmentQuery (user) {
if (Roles.userHasRole(user._id, "Admin"))
return {};
else if (Roles.userHasRole(user._id, "HQ"))
return {company: user.profile.company};
else if (Roles.userHasRole(user._id, "Branch"))
return {branch: user.profile.branch};
else
throw new Error('getEnrollmentQuery: unknown role for user (' + user._id + ')');
}
Meteor.publish("enrollments", function (limit) {
var user = Meteor.users.findOne({"_id": this.userId}, {fields:{profile: 1}});
var query = getEnrollmentQuery(user);
Counts.publish(this, 'enrollmentsCount', Enrollments.find(query), {noReady: true});
if (limit) {
return Enrollments.find(query);
} else {
return Enrollments.find(query, {limit: limit}) ;
}
}); And your subscription routine becomes: Meteor.subscribe("enrollments", 5);
console.log("enrollment count: ", Counts.get("enrollments")); This version is more secure since your users can't manually invoke the |
Hi @boxofrox , It worked! :) However, it seems that it didn't count during first load, i have to reload the page to see the actual count. BTW, I put the subscription on the router. what is the significance of 5 inside subscription? ("enrollments", 5) Thanks! |
I don't know what you mean by first load. It sounds like there is some task performed by the browser/server before the user can visit the page in question. Once there a reload fixes the count. If you can reproduce that behavior, what happens when you visit the page (first load), open the dev-tools console, and run If the latter, then your template may not be reactively updating when the initial count is generated after the page loads.
5 is an arbitrary number I used for the
You're welcome to leave it out. |
I mean by first load is after logging in the application, after the user logged in, console log 0 count, then reload/refresh browser, it will display the actual document count. The subscription is in the router, It didn't work, then I moved it in the main template logic (dashboard.js) and wrapped in What is the effect if I change the limit 5 to other number or remove it? Sorry for the newbie question. I'm trying to understand the concept. Thanks @boxofrox. |
Ah, that makes sense. I've not done user logins or used routes, so I'm not sure where the problem would be. I think we've sorted out the problem for this issue and found a new issue with setting up subscriptions with the router. If you're working with your meteor-insurance repository, push the changes you have so far and I can try reproducing the issue on my end. If you'd rather keep your commits private, that's fine, too.
Typically our datasets are unbounded, and we don't want every client downloading 100,000+ documents, so we limit them to a smaller subset. If you wanted to add pagination so the user could view 25 records or so per page, you could add a If you never use the
No worries |
Hi @boxofrox , Here's the repo for repro here. Btw, i have other collection that require a document count also but you can ignore that, as soon we solve the first issue, I will try to work that. I can now understand the limit. You can uncomment the code on server > fixture.js for the admin credential. Thanks Again! |
Let's move this conversation into gitter for a bit. i think you'll have to set up the room, first. |
Hi @boxofrox , I've managed to achieve what I want. I've put my subs on my router and it worked. However, i have this one last requirement which I will file later. Thanks for your help! |
My pleasure. Cheers. |
Hi,
I have a collection which has a user profile field, i grab the user profile using autovalue on collection2.
How do I count the published document of a user based on his profile?
users profile has
Expected result is different per user.
Appreciate any help.
The text was updated successfully, but these errors were encountered: