here is the deal:
I have two models - User and House
User has many houses
House belongs to a User
I've entered some dummy data and created a minimal express app to serve an api
I want to return a list of users and include each users houses.
the api endpoint looks like this:
router.get('/users', function(req, res,next) {
models.User.findAll({
include: [ models.House ],
raw: true // returns result-set as a clean json...
})
.then(function(users) {
d('num users found: ' + users.length);
res.json(users);
})
.catch(function(err){
d('DB ERROR: '+err.message);
next(err);
});
});
The default behavior of Sequelize is to return multiple instances of the same User data, each time with a different house data like so:
[
{
id: 1,
first_name: "aa",
last_name: "aaaaaa",
email: "[email protected]",
Houses.id: 1,
Houses.description: "house 1 desc",
Houses.user_id: 1
},
{
id: 1,
first_name: "aa",
last_name: "aaaaaa",
email: "[email protected]",
Houses.id: 3,
Houses.description: "house 3 desc",
Houses.user_id: 1
},
{
id: 2,
first_name: "bb",
last_name: "bbbbbb",
email: "[email protected]",
Houses.id: 2,
Houses.description: "house 2",
Houses.user_id: 2
}
]
Can I get an array of houses embedded in the owning user?
Is there a way to configure Sequelize to return the data like so:
[
{
id: 1,
first_name: "aa",
last_name: "aaaaaa",
email: "[email protected]",
Houses:[
{
id: 1,
description: "house 1 desc",
user_id: 1
},
{
id: 3,
description: "house 3 desc",
user_id: 1
},
]
},
{
id: 2,
first_name: "bb",
last_name: "bbbbbb",
email: "[email protected]",
Houses:[
{
id: 2,
description: "house 2",
user_id: 2
}
]
}
]
If the answer is no, can you recommend of a way to parse the data into such a structure?
The User Model:
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('User', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
email: DataTypes.STRING
},
{
classMethods: {
associate: function(models) {
User.hasMany(models.House)
}
}
});
return User;
};
The house model:
module.exports = function(sequelize, DataTypes) {
var House = sequelize.define("House", {
description: DataTypes.TEXT
},
{
classMethods: {
associate: function(models) {
House.belongsTo(models.User);
}
}
});
return House;
};
I had a similar problem and just found a solution that seems to work in my case:
router.get('/users', function(req, res, next) {
models.User.findAll({
include: [ {model: models.House, as: 'houses'} ],
raw: false // returns result-set as sequelize object...
})
.then(function(users) {
users = users.get(); //turns sequelize object into json
d('num users found: ' + users.length);
res.json(users);
})
.catch(function(err){
d('DB ERROR: '+err.message);
next(err);
});
});
Set raw to false (or let it default to that), then, anytime you need to get the raw json before the res.json, use users.get()
("users" now being a sequelize instance) and you can get the json of that sequelize object that is now an object with an array of its associations!
models.User.findAll({
include: [ models.House ],
nest: true
})
add nest attribute to your query
remove raw true
for more related to issue
github-sequelize-issue 3885
stackoverflow-questions-61532849
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With