SailsJs get list of objects population relationships - javascript

I have a model Post:
// Post.js
attributes:{
name: {type:"string"},
users: { collection: 'user', via: 'postsReceived' },
category: { model: 'category' },
// Plus lots of other fields and relationships to other models for example category, topic, etc...
}
And I have a model Users:
// Users.js
attributes:{
name: {type:"string"},
postsReceived: { collection: 'post', via: 'users', dominant: true }
}
A post can be sent to many users and a user may have many posts. This if fine however when it comes to populating a list of posts that a user is attached to this becomes quite difficult. I am using the below code to get the list of posts, however this does not populate the posts relationships. For example the below will only return a id for the category of the post. What is the best way (in terms of performance) to get this to work?
User.findOne({id:id})
.populate('postsReceived')
.exec(function(err, user){
if(err) return res.serverError(err);
if (user){
var result = user.postsReceived;
return res.json(result);
}
});

I found a solution for this that seems to work quite nicely from:
This Answer
The answer in the question above suggets using sails-hook-orm-offshore

Related

js sequelize chain association accessors

I have three models: Url, Action, Container
I would like to get the Container of a Url through the following relations:
db.Url.belongsTo(db.Action, { foreignKey: 'action_id'});
db.Action.belongsTo(db.Container, { foreignKey: 'container_id'});
I was hoping for something like:
db.Url.findOne(...).getAction().getContainer()
However it only seems to work when I work with the entities one after another.
i.e. query the db for the url. Then call url.getAction() and then getContainer.
So it is three separate querys instead of one.
So you are asking for a nested include? I don't quite understand what you need to find, the Container through a given Url.id?? Anyaways you're looking for something like this
db.Url.find({
include: [
{
model: db.Action,
include : [{
model: db.Container
}]
}
]
})
.then(function(response) {
return res.json(response);
})
.catch(function (err) {
// more code...
});
This will a return a single json with all corresponding associations.

Sails.js populate filter

I am trying to get all of my posts' comments which comments count is greater than 0. I am tying to add the where in find and populate, but none of it worked.
Post model:
module.exports = {
attributes: {
user: {
model: 'user'
},
comments: {
collection: 'comment',
via: 'post'
}
};
PostController:
Post
.find({comments: {'>': 0}, user: me})
.populate('comments')
.exec(function(err, comments){
res.json(comments);
});
In current Sails/Waterline relations implementation you can't filter by one-to-many related fields. You need to filter the result after find is completed.

Meteor User table value axtracting

How do I pick the email address value from meteor Mongo user table?
I have written below query to pick the element:
users=Meteor.users.find({},{emails:1})
This the code I have written to fetch the email address, but I don't know how much it's affecting performance in the code:
users = Meteor.users.find({})
users.forEach(function(key,option){
key.emails.forEach(function (key,option){
console.log(key.address)
});
});
In meteor, you should call:
users = Meteor.users.find({}, { fields: { emails: 1 } })
Reference in docs
EDIT
Please remember users is a cursor object. Cursor objects can be handled directly in templates, and must be the return of publications. You can't iterate a cursor directly in a javascript loop.
Example: (remember authorization in production publications)
Meteor.publish('user-emails', function() {
return Meteor.users.find({}, { fields: { emails: 1 } });
});
If you want to directly access the user instances, for example to iterate them in a javascript code, you need to fetch the cursor (reference in docs).
Example:
var users = Meteor.users.find({}, { fields: { emails: 1 } }).fetch();
Now users is an array of users. Feel free to iterate them.
Example (I'm using underscore.js):
var users = Meteor.users.find({}, { fields: { emails: 1 } }).fetch();
_.each(users, function(user) {
console.log(user.emails);
});
Now, if you need a vector only with emails, one on each index, you can pluck the emails from a fetched array with underscore.js (reference of pluck)
var emails = _.pluck(Meteor.users.find({}, { fields: { emails: 1 } }).fetch(), 'emails');
Hope it works :)
if its not working, dont forget to return
return users

Publish a collections and other collection's documents which have relation with any document in the first collection

The scenario is that I want to publish one whole collection and users' data (such as profile) who have relation with any document in the the first collection.
The problem is how can I publish that part of users collections?
Well, there are two ways, first is using package
https://atmospherejs.com/cottz/publish-with-relations
And second one - in publish function you can return multiple cursors, from docs
Meteor.publish("roomAndMessages", function (roomId) {
check(roomId, String);
return [
Rooms.find({_id: roomId}, {fields: {secretInfo: 0}}),
Messages.find({roomId: roomId})
];
});
After some research, I found reywood:publish-composite solved my problem completly.
Example:
Meteor.publishComposite('getItemsList', {
find: function() {
return Items.find({});
},
children: [
{
find: function(item) {
return Meteor.users.find(
{ _id: item.userId },);
}
}
]});
This will publish all the items documents with any user document that have a relation with it. ( Items.userId is mapped to Meteor.users._id )

SailsJS v0.10 multiple model associations

I have 3 models. User, Profile and comments.
Profile is an association of User (one to one) and comments are an association of Profile (one to many).
User Model:
attributes: {
profile: {
model: 'Profile'
},
}
Profile Model:
attributes: {
comments: {
collection: 'profileComment',
via: 'profile'
}
}
Comments model:
attributes: {
profile: {
model: 'Profile'
},
}
Getting the user profile works fine:
User.findOneById(id)
.populate('profile')
.exec(function (err, user) {
// user.profile
});
But then how would I populate the profile with the comments?
It seems like you could back into what you want by setting a user attribute on profile:
attributes: {
comments: {
collection: 'profileComment',
via: 'profile'
},
user: {
model: 'User'
}
}
And then querying with:
Profile.findOne({user: userId})
.populate('user')
.populate('comments')
.exec(function(err, profile) {
// use profile.user and profile.comments
});
Keep in mind, however, that Waterline doesn't currently implement true one-to-one associations, so if you set a Profile instance's user attribute to 123, the corresponding User instance won't automatically have its profile attribute set. This may not be a big deal--you can always look up Profile and populate User, like in the example above--but it's something to keep in mind.
Your other option is to keep things as they are and do a mapping, as in this question and answer.

Categories

Resources