I set up user management in my app with accounts-base and some additional packages. As a result, I have a user collection in the DB.
I now want to store some information related to a user profile (favorites of various entities that the user selects in the app).
What is the best practice of where to store that information?
I recall from other frameworks that were based on RDBS that it was usually recommended to create a separate entity extending the base user to “separate concerns”.
Or is there nothing much speaking against just adding attributes to user documents?
We’re going to suggest adding new top-level fields to the users collection, mostly because the two other options aren’t great:
Using a sub-field like profile doesn’t work well because DDP can only send updates on top-level fields; this means you can’t really publish only some of profile to different users.
Using a totally different collection doesn’t work well with Mongo since there aren’t good ways of managing related collections, especially when they are very tightly coupled.
In the favorites case, though, I think it might actually be better to have a separate collection of just the “favorites”.
So it depends on how many favorites you would envision each user having. If it’s not that many, then it’s OK to keep them in an array. If it’s a huge number, like > 1000, it could be good to normalize. Because in Meteor, there isn’t any smart diffing of arrays on the network level - every time you add a new item to the array it will resend the whole thing. Perhaps that isn’t a big problem.
Do you envision showing who favorited certain entities in your app? Like on Twitter, where you can see who favorited each tweet?
Thanks again for elborating, greatly appreciated (hadn’t considered the network level aspect, for example).
But for now, mine is a very small app for publishing quotes. Users should be able to favorite them, and for each user I want to show the quotes he added to favorites, as well as show a count for each quote that shows the number of users that added it as a favorite.
Yeah so the best approach there is probably tracking the number of favorites as a field on each individual quote, and then having an array on each user. Looks like you’re on the right track!
There is a bug in the file “client/events.js”, line 4, which is displayed in the console when you click on “save”. Replace:
event.preventDefault();
by:
events.preventDefault();
Data is correctly updated in the “users” MongoDB collection when you click on “save”. You can check that running:
meteor mongo
then in the shell:
db.users.find()
You didn’t remove the stupid “autopublish” and “insecure” packages. First thing to do is removing that crap out of your Meteor project. It must be a reflex. I don’t understand why they are added by default. They give bad security habits to beginners and experts don’t need that since their code has good design. This is nonsense. Maybe useful for people who debug Meteor itself but definitely not something for everyone.
There are curly braces in file “server/publications.js”, line 1, arround the “userIds” parameter. I don’t know why they did that in the tutorial, but this is clearly an issue. If you add this code in this file on line 2:
console.log(">>>>> userIds value is:", userIds);
and look at the console, you’ll see that it’s undefined. Now remove the curly braces on line 1 and try again: value is the one from Meteor.userId().
For some reason the code in file “server/publications.js” from line 3 to 5:
new SimpleSchema({
userIds: { type: [String] }
}).validate({ userIds });
doesn’t validate and consequently prevents the code from running further to this point. Comment out theses 3 lines and it will keep running. You can check proof of what I’m saying by adding this code on line 6:
console.log("Running")
You will see that this line is not displayed before you comment out the three said lines.
Your publication filters on the keys “name”, “age” and “gender”. First the “gender” key doesn’t exist, it’s called “sex” in your database. Second these are not top-level keys in your “users” collection. They are sub-documents of the main document called “detail”. So in file “server/publications.js” change line 14 from:
I won’t talk about the huge security flaws in this code because it’s a demo app and I assume it was just made to understand how publications work. I just hope that you are aware that this code is totally insecure by design (for example: you can invoke the Meteor method with any userId and consequently update the profile of someone else).
it will publish the 3 sub-documents, and if I use this:
fields: {"detail.name": 1, "detail.sex": 1}
it will publish only the 2 sub-documents (EDIT: and the future updates of these sub-documents). The third is not sent to the end-user despite the fact that it’s not a top-level document.
However your post was about 6 months ago so maybe Meteor updates changed that behaviour since then.