I am new to sails.js and I am using "sails.js with Mongodb". I am having problem with deep associations using populate in my sails app.
I have a relationship like this:
Category has many to many relationship with Article.
City has one to many relationship with Areas.
Article has one to one relationship with City and Areas.
Category.js
module.exports = {
schema: true,
attributes: {
//add referecnce to other article
Articles: {
collection: 'Article',
via:'ref_category_id'
},
category_name: {
type:'string',
required: true,
unique: true },
}
};
Article.js
module.exports = {
schema: true,
attributes: {
//adding reference to category
ref_category_id: {
collection:'Category',
via:'Articles'
},
//adding reference to city
ref_city_id: {
model:'City'
},
//add a reference to area
ref_area_id: {
model:'Areas'
},
//adding reference to tags
tags: {
collection: 'Tag',
via:'articles'
},
title:{ type:'string',required:true},
blurb: { type: 'string'},
description:{ type:'string'}
}
};
City.js
module.exports = {
schema: true,
attributes: {
Areas: {
collection: 'Areas',
via:'ref_city_id'
},
ref_article_id:{
model:'Article'
},
city_name: { type:'string',
required:true,
unique:true }
}
};
Areas.js
module.exports = {
schema: true,
attributes: {
area_name: { type:'string',required:true},
latitude: { type:'float'},
longitude: { type:'float'},
ref_city_id: {
model: 'City'
},
ref_article_id:{
model:'Article'
}
}
};
Tag.js
module.exports = {
schema:false,
attributes: {
//adding reference to article
articles: {
collection: 'Article',
via:'tags'
},
tag_name:{type:'string',
required:true,
unique:true
}
}
};
CategoryController.js
searchCategory: function(req, res, next) {
var category_name = req.param('category_name');
Category.find({category_name:{'like': '%'+category_name+'%'}}).populate('Articles').exec(function(err, category)
{
if(err)
{
return res.json({'status':486,'status_message':'Server Error'});
}
else
{
if(category.length > 0)
{
var c = parseInt(category[0].Articles.length,10);
console.log(c);
var i = parseInt('0',10);
for (i=0; i<c; i++)
{
console.log('i value in loop = ' + i);
Article.find({id:category[0].Article[i].id}).populateAll().exec(function(err,article_info) {
if(err)
{
return res.send(err);
}
else
{
console.log(article_info);
console.log('-------------------------------------------');
res.json(article_info);
console.log(' I value = ' + i);
}
});
}
//console.log(category);
//return res.json({'status':479,'status_message':'Success..!!','category_info':category});
}
else
{
return res.json({'status':489,'status_message':'failure..!! No categories found..!!'});
}
}
});
}
POSTMAN Request:
http://localhost:1337/category/searchCategory
{"category_name":"travel"}
This is my json response: Here I am getting only article which is mapped with category. but i wanted to display the values of city, areas and tags which are mapped to article.
{
"status": 479,
"status_message": "Success..!!",
"category_info": [
{
"Articles": [
{
"ref_city_id": "55a766d0a29811e875cb96a1",
"ref_area_id": "55a78b69578393e0049dec43",
"title": "title",
"blurb": "blurb",
"description": "Description",
"createdAt": "2015-07-16T12:36:36.778Z",
"updatedAt": "2015-07-16T12:48:20.609Z",
"id": "55a7a55439ace79e0512269d"
},
],
"category_name": "Cooking ",
"id": "55a6b26aee9b41de747547bb",
"createdAt": "2015-07-15T19:20:10.670Z",
"updatedAt": "2015-07-15T19:20:10.670Z"
}
]
}
How to do the deep nested associations using populate? or Is any other way to achieve this?
Please Can anyone help me to achieve this.
Thanks in advance.
Yes, there is another way to do this.
Make sure you require the following npm module.
var nestedPop = require('nested-pop');
searchCategory: function(req, res, next) {
var category_name = req.param('category_name');
Category.find({category_name:{'like': '%'+category_name+'%'}})
.populate('Articles')
.exec(function(err, category) {
if(err) return res.json({'status':486,'status_message':'Server Error'});
if(category.length > 0) {
var c = parseInt(category[0].Articles.length,10);
console.log(c);
var i = parseInt('0',10);
for (var i = 0; i < c; i++) {
console.log('i value in loop = ' + i);
Article.find({id:category[0].Article[i].id})
.populateAll()
.exec(function(err, article_info) {
if(err) return res.send(err);
return nestedPop(article_info, {
ref_city_id: {
as: 'City',
populate: [
'things',
'you',
'want',
'to',
'populate',
'for',
'city'
],
},
ref_area_id: {
as: 'Area', // or Areas (whatever the model name is)
populate: [
'things',
'you',
'want',
'to',
'populate',
'for',
'area'
]
}
}).then(function(article_info) {
console.log(article_info);
console.log('------------------------------------------');
res.json(article_info);
console.log(' I value = ' + i);
});
});
}
} else {
return res.json({'status':489,'status_message':'failure..!! No categories found..!!'});
}
});
}
Go to https://www.npmjs.com/package/nested-pop for more documentation.