-
Notifications
You must be signed in to change notification settings - Fork 642
Description
Version: 2.2.14
Driver: mysql, but fails with sqlite3 as well (Driver doesn't seem to be related)
Problem description:
Using the base reproduction-template.js file, I added the following code:
// This one works just fine
const jenniferPets = await (await Person.query()
.findOne({ firstName: 'Jennifer' }))
.$relatedQuery('pets');
const jennifer = await Person.query().findOne({ firstName: 'Jennifer' });
// This one does not. Jennifer has no parent and, therefore, the pets of the non-existent parent should be unexistent
// However, all of the existing pets (in this case, only one) are retrieved.
const jenniferParent = await jennifer.$relatedQuery('parent');
const jenniferParentPets = await Person.relatedQuery('pets').for(jennifer.$relatedQuery('parent'));
// This one fails as well and throws an exception
const jenniferParentPetsInstance = await Person.relatedQuery('pets').for(jenniferParent);
// However, this one works as expected
const jenniferParentPetsIndex = await Person.relatedQuery('pets').for(Person.relatedQuery('parent').for(jennifer.id));
chai.expect(jennifer.pets[0].name).to.equal('Doggo');
// Test fails as an empty array should be returned.
chai.expect(jenniferParentPets.length).to.equal(0);
chai.expect(jenniferParentPetsInstance.length).to.equal(0);
// Test succeed
chai.expect(jenniferParentPetsIndex.length).to.equal(0);It seems there is a problem when a field related to a BelongsToOne relationship is null. It causes queries using this subquery to fetch all of the available target model instances incorrectly.
However, the expected behaviour is obtained by using the instance id as demonstrated in the replication set up.
After using debug(), this is the select generated for the first failing query:
select `Animal`.* from `Animal` where `Animal`.`ownerId` in (select `Person`.`id` from `Person`)So it seems the problem is related to the sql subquery that is generated for the modelInstace.$relatedQuery() method when modelInstance does not belong to any target model.
Attaching reproduction-template.js in case it helps. Also, not sure this is only related to BelongsToOne relationships. It seems any querybuilder that fetchs either one model instance or undefined could display the same behaviour.
PS: I think it is useful that the for() method is able to handle "falsy" values as using it with queries that fetch no results wouldn't need any prior checks on the application code so that would also be a neat addition