I'd like to conditionally add a where clause to my query so that it filters the results by a column in an associated model, of an associated model.
ie: Application => Job => filter by column of Company
currently I can only filter by a column in the Job table
These are the associations:
Applicant.belongsToMany(Job, {through: Application})
Job.belongsToMany(Applicant, { through: Application });
// Associations so the Application table can be directly queried
Application.belongsTo(Job, { foreignKey: { name: 'jobId' }});
Application.belongsTo(Applicant, { foreignKey: { name: 'applicantId' } });
Company.hasMany(Job, { foreignKey: { name: 'companyId', allowNull: false} });
Job.belongsTo(Company, { foreignKey: { name: 'companyId', allowNull: false} });
As above, I'd like to return all the applications where the column name in the Company model is similar to a searchTerm
I can currently return only the relevant applications where the column title in the Job model matches, but if I try to filter by a more deeply nested model, like Company it doesn't work
Here's how I add a where clause to the options object to filter by job.title:
const options = {
order: // ...
distinct: true,
attributes //...
include: [
{
model: Job,
include: [
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Contact,
separate: true,
include: [{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}]
}
]
}
]
},
{
model: Applicant,
include: [
{
model: Person,
attributes: [ 'id', 'firstName', 'lastName', 'email', 'phone', 'createdAt' ]
}
],
}
];
}
if(x) options.include[0].where = { title: { [Op.like]: `%${searchTerm}%` } };
const results = Application.findAll(options)
This returns only the applications that have jobs with a similar title to the searchTerm. Which is what I want, but I suspect that this is a mistake that just coincidentally works the way I want it to.
If I try to achieve my real aim - to return only the applications that have a job with a certain company name - I add the following to the options object using similar logic:
if(x) options.include[0].include[0].where = { name: { [Op.like]: `%${searchTerm}%` } };
... but that returns all the applications, with null for the job and company where the where clause doesn't match
Just to clarify, this isn't what I'm after - I'm trying to get only the applications where the company name is like the searchTerm.
Appreciate any help, let me know if I haven't been clear enough!
So I think I've found the answer: I've been confusing nested where clauses with refering to nested columns from the top-level where clause using the $nested.column$ syntax.
So I can do $nested.nested.column$ and it seems to work:
options.where = {'$job.company.name$': { [Op.like]: ``%${searchTerm}%`` }}
Although I'm still confused as to why my query filtering by a Job column works as expected.