Reputation: 1343
The following code should return 12 rows (req.query.limit
= 12). This works fine if I don't include any associated rows, but when I include the related models it returns 7 rows.
I think it's down to me using the property subQuery: false
which allows me (if I remember correctly) to order my results by column correctly - but it's been a long time since I've looked at the ordering code, I'm not very proficient with sequelize, and don't want to break it unnecessarily!
Would really appreciate it if someone can spot where I'm going wrong, and maybe why?
exports.getApplications = async(req, res, next) => {
const index = req.query.index || 0;
const limit = req.query.limit || 10;
const order = req.query.orderDirection || 'DESC';
let orderFields;
switch(req.query.orderField) {
case 'lastName':
orderFields = [
['applicant', 'person', 'lastName'],
['applicant', 'person', 'firstName'],
['applicant', 'createdAt', order]
];
break;
default:
orderFields = [ 'createdAt' ];
}
try {
const applications = await Application.findAndCountAll({
include: [
{
model: Job,
include: [
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}
]
}
]
},
{
model: Applicant,
include: [
{
model: Person,
attributes: [ 'id', 'firstName', 'lastName', 'email', 'phone', 'createdAt' ]
}
],
}
],
subQuery: false,
order: orderFields,
limit: parseInt(limit, 10),
offset: parseInt(index),
distinct: true,
attributes: [
'id',
'applicantId',
'jobId',
[Sequelize.fn('date_format', Sequelize.col('application.createdAt' ), '%d/%m/%y'), 'applicationDate']
]
});
console.log(applications.rows.length); // 7 -- wrong
console.log(limit); // 12 -- correct
res.status(200).json({msg: 'success', applications: applications});
} catch (err) {
console.log(err);
}
Associations:
Company.hasMany(Job, { foreignKey: { name: 'companyId', allowNull: false} });
Job.belongsTo(Company, { foreignKey: { name: 'companyId', allowNull: false} });
Person.hasOne(Applicant, { foreignKey: { name: 'personId', allowNull: false, unique: true } });
Applicant.belongsTo(Person, { foreignKey: { name: 'personId', allowNull: false, unique: true } });
Applicant.belongsToMany(Job, { through: Application });
Job.belongsToMany(Applicant, { through: Application });
// Set associations so the Application table can be queried directly
Application.belongsTo(Job, { foreignKey: { name: 'jobId' }});
Application.belongsTo(Applicant, { foreignKey: { name: 'applicantId' } });
Person.belongsToMany(Company, { through: Contact });
Company.belongsToMany(Person, { through: Contact });
Upvotes: 0
Views: 2247
Reputation: 22803
In order to properly use findAndCountAll
you need to get rid of many-to-many
in include
option OR convert it to one-to-many
and use separate: true
option.
associations
Company.hasMany(Contact, { foreginKey: 'companyId' });
Contact.belongsTo(Person, { foreginKey: 'personId' });
possible include option
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Contact,
separate: true,
attributes: [],
include: [{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}]
}
]
}
And yes, you will get an extra level to get person attributes through Contact
.
Upvotes: 1