Unknown Column in BelongsToMany relation with Eager Loading
See original GitHub issueSequelize Model doesnot fire a proper query for belongsToMany relation with a top-level where condition and hence resulting in an unknown column error.
I have 3 models:
- User(id, name, role = [CEO or Manager or Intern])
- Task(id, name, type)
- TaskAssigned(id, task_id, user_id)
Lets consider the following Relations:
-
User belongsToMany Task through TaskAssigned
-
User hasMany TaskAssigned
-
Task hasOne TaskAssigned
-
TaskAssigned belongsTo Task
-
TaskAssigned belongsTo User
What are you doing?
I want to fire a query which would give me all the tasks of a particular type which either have been assigned to a user of a particular type i.e. “intern” or not assigned at all.
There are two ways to perform this query:
Method 1
Task.findAll({
include: [{
association: TaskAssigned,
include: 'User',
required: false
],
where: {
'$TaskAssigned.User.role': {
[Op.or]: ['intern', {[Op.eq]: null}]
}
}
};
Performing the above results in the following query:
SELECT `Task`.`id`, `Task`.`name`, `Task`.`type`, `TaskAssigned`.`id` AS `TaskAssigned.id`, `TaskAssigned`.`task_id` AS `TaskAssigned.task_id`, `TaskAssigned`.`user_id` AS `TaskAssigned.user_id`, `TaskAssigned->User`.`id` AS `TaskAssigned.User.id`, `TaskAssigned->User`.`name` AS `TaskAssigned.User.name`, `TaskAssigned->User`.`role` AS `TaskAssigned.User.role` FROM `tasks` AS `Task`
LEFT OUTER JOIN `task_assigned` AS `TaskAssigned` ON `Task`.`id` = `TaskAssigned`.`task_id`
LEFT OUTER JOIN `users` AS `TaskAssigned->User` ON `TaskAssigned`.`user_id` = `TaskAssigned->User`.`id`
WHERE ((`Task`.`type` = ‘todo’ AND (`TaskAssigned->User`.`role` = ‘intern’ OR `TaskAssigned->User`.`role` IS NULL)))
The above mentioned query works perfectly.
Method 2 However if I try to perform a similar query using the belongsToMany relation,
Task.findAll({
include: [{
association: User,
required: false
],
where: {
'$User.role': {
[Op.or]: ['intern', {[Op.eq]: null}]
}
}
};
an error of Unknown column ‘User.id’ not found
SELECT `Task`.*, `User`.`id` AS `User.id`, `User`.`name` AS `User.name`, `User`.`role` AS `User.role`, `User->TaskAssinged`.`id` AS `User.TaskAssigned.id`, `User->TaskAssinged`.`user_id` AS `User.TaskAssigned.user_id`, `User->TaskAssinged`.`task_id` AS `User.TaskAssigned.task_id` FROM (
SELECT `Task`.`id`, `Task`.`name`, `Task`.`type` FROM `tasks` AS `Task` WHERE ((`Task`.`type` = ‘todo’ AND (`User`.`role` = ‘intern’ OR `User`.`role` IS NULL)))) AS `Task`
LEFT OUTER JOIN ( `task_assigned` AS `User->TaskAssinged` INNER JOIN `users` AS `User` ON `User`.`id` = `User->TaskAssinged`.`user_id`) ON `Task`.`id` = `User->TaskAssinged`.`task_id`;
What is actually happening?
If you look at the query, the condition
(`User`.`role` = ‘intern’ OR `User`.`role` IS NULL)`
is not placed at the proper place i.e. It is placed within a sub-query of Tasks table
What do you expect to happen?
A proper SQL query in which the condition
(`User`.`role` = ‘intern’ OR `User`.`role` IS NULL)`
is a top-level where condition placed at the end of the query as in the Method 1 case .
Meta Information
__Dialect: mysql __Dialect version: __Database version: 5.7 __Sequelize version: 4.43.0 __Tested with latest release: Latest v4 release
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (5 by maintainers)
I got a SSCCE ready to work, but for an unknown reason, I am currently unable to reproduce the issue on the same sequelize version mentioned above. The query generated by both the methods are correct without the above mentioned issue.
Although, I’ll try the same thing out at a later point to see where was the fault.
Still waiting for a revert on this issue.