Reputation: 9216
I'm currently experimenting with Sequelize and have two objects, a Person
and Position
, When getting a list of persons I want to get their position.
models:
var User = sequelize.define('user', {
first_name: Sequelize.STRING,
last_name: Sequelize.STRING
});
var Position = sequelize.define('position', {
name: Sequelize.STRING,
affiliation: Sequelize.STRING
});
Position.hasMany(User, { foreignKey : 'position_id' });
User.belongsTo(Position, { foreignKey : 'position_id'});
My query:
User.findAll({ fetchAssociations: true }, function(results) {
//I've tried doing some work in here, but haven't found the correct procedure.
}).on('success', function(results) {
res.render('users', {
title: 'user page',
users: results
});
});
Watching the log it never queries Person
at all. Do I need to use queryChaining? From the documentation I was able to find it appeared it should auto fetch associations.
Upvotes: 7
Views: 9729
Reputation: 96
This allow serialize a json for anywhere action about a model. Read it, very well, i think that is the best way
// define models
var Person = sequelize.define('Person', { name: Sequelize.STRING });
var Task = sequelize.define('Task', {
name: Sequelize.STRING,
nameWithPerson: {
type: Sequelize.VIRTUAL,
get: function() { return this.name + ' (' + this.Person.name + ')' }
attributes: [ 'name' ],
include: [ { model: Person, attributes: [ 'name' ] } ],
order: [ ['name'], [ Person, 'name' ] ]
}
});
// define associations
Task.belongsTo(Person);
Person.hasMany(Task);
// activate virtual fields functionality
sequelize.initVirtualFields();
Upvotes: 0
Reputation: 2828
From April 2013 in v1.7.0 you need just to expand your Associations to:
Position.hasMany(User, {foreignKey : 'position_id', as: 'User'});
User.belongsTo(Position, {foreignKey : 'position_id', as: 'Posit'});
and then find all Users with associated Positions
User.findAll({
include: [{
model: Position, as: 'Posit'
}]
}).success(function(match) {
// your logic
});
Upvotes: 8
Reputation: 6241
Ok here a complete example how to fix your problem (and yeah that's crap):
User.findAll().on('success', function(users) {
var chainer = new Sequelize.Utils.QueryChainer
, _users = []
users.forEach(function(u) {
var emitter = new Sequelize.Utils.CustomEventEmitter(function() {
u.getPosition().on('success', function(pos) {
_users.push({user: u, position: pos})
emitter.emit('success')
})
})
chainer.add(emitter.run())
})
chainer.run().on('success', function() {
res.render('users', {
title: 'user page',
users: _users
})
})
})
This will first get all the users, then get the position of each user and save them in the _users-array. Afterwards it renders the page. It's not tested but should do the trick.
Upvotes: 5
Reputation: 6241
since I rewrote sequelize for 1.0 I removed the support of fetchAssociations. I will add it in the next weeks. But let's take a look at your code:
You are using underscore-like column names, so you probably want to use the underscore option for automatically generated columns: http://www.sequelizejs.com/?active=usage#usage --> scroll a bit down or search for underscore. This might save you the options for belongsTo/hasMany.
What you want to do with findAll is smth. like this:
User.findAll().on('success', function(users) {
// asd
})
And as I just noticed... it's somewhat tricky to get all associated objects :D So much for now. Hope that helped.
Upvotes: 4