-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
find({ ... }) doesn't intelligently handle associations #293
Comments
I'm working on this right now. |
Ah, was also looking into it. Appears somewhat more complicated to fix nicely than I first expected - since conditions can also be used in table joins, and there doesn't appear to be any central point that they all pass through. Currently working on adding a method to Model which preprocesses conditions, and then I'll try to get merge options to pass through that as well (or something similar). It also appears that this only affects |
I'm just pointing my batteries to hasOne associations. I'm just going to update to support |
This allows people to do { owner: [ owner1, owner2, .. ] }
Appears to be working correctly for |
Please add some tests if you have time :) |
Will do |
Hmm, just looked through your implementation fully and looks like there is currently no support for multiple primary keys. Unfortunately, adding support for multiple values AND primary keys requires that we add some additional functionality to node-sql-query. Basically, if we want to support something like this Pet.find({ owner: [owner1, owner2] }, function(err, pets) {
//pets with either owner1 or owner2 as their owner, implied by same syntax as { owner_id: [owner1.id, owner2.id] }
}); we would need to add support for generating of a SQL query like SELECT * FROM `pets` WHERE (`owner_id1` = `1` AND `owner_id2` = `1`) OR (`owner_id1` = `2` AND `owner_id2` = `2`) My proposal would be for a custom conditions object which provides logical handling along the lines of var conditions = ORM.conditions({ cond1: 'val1' }).and({ cond2: 'val2' }).or(ORM.conditions({ cond1: 'val11'}).and({ cond2: 'val22' })); Thus, it should support chaining on the The var conditions = ORM.conditions({ name: 'John'});
// `name` = 'John'
conditions = conditions.and({ surname: 'Doe' });
// `name` = 'John' AND `surname` = 'Doe'
conditions = conditions.or({ name: 'Sally', surname: 'Black'});
// (`name` = 'John' AND `surname` = 'Doe') OR (`name` = 'Sally' AND `surname` = 'Black') |
Improves support for multi-key objects, still missing the ability to handle multi-value conditions for multi-key objects. Added a test to verify that it does work correctly for single-primarykey objects with multiple possible values (generates a `foreignkey` IN ('val1', 'val2'...) statement)
Improves support for multi-key objects, still missing the ability to handle multi-value conditions for multi-key objects. Added a test to verify that it does work correctly for single-primarykey objects with multiple possible values (generates a `foreignkey` IN ('val1', 'val2'...) statement)
Improves support for multi-key objects, still missing the ability to handle multi-value conditions for multi-key objects. Added a test to verify that it does work correctly for single-primarykey objects with multiple possible values (generates a `foreignkey` IN ('val1', 'val2'...) statement)
Improves support for multi-key objects, still missing the ability to handle multi-value conditions for multi-key objects. Added a test to verify that it does work correctly for single-primarykey objects with multiple possible values (generates a `foreignkey` IN ('val1', 'val2'...) statement)
Improves support for multi-key objects, still missing the ability to handle multi-value conditions for multi-key objects. Added a test to verify that it does work correctly for single-primarykey objects with multiple possible values (generates a `foreignkey` IN ('val1', 'val2'...) statement)
sql-query supports https://github.com/dresende/node-sql-query/blob/master/test/integration/test-where-advanced.js |
Ah, neat. Let me see what I can do about adding it now |
Okay, just a quick question - is it fine if I use Model.table to determine equality between models? Can't think of any other nice way to do it, since it is necessary to ensure that only instances of the type required by the relevant property are processed. |
I think it's OK for now, but you can create an uid value or something (like Instance has using |
Okay, let me do that instead then. Having issues at the moment getting tests to pass for SQLite, it appears to dislike returning a valid owner object when matching on |
Okay, another question: Why are we using a different primarykey format for MongoDB? |
MongoDB default id is "_id" (automatically added). I don't have enough experience to know how to change this name. |
Hmm, okay. Also looks like MongoDB automatically increments that ID on changes to the model - which makes some of the tests in my suite fail. I'm tempted to just check the |
The _id does never change. If it's changing it might be because of recreating instances. |
Well here's the test I was running, and _id was being incremented on the same model by the looks of it. var setup = function () {
return function (done) {
Person = db.define('person', {
name : String
});
Pet = db.define('pet', {
name : String
});
Person.hasOne('pet', Pet, {
reverse: 'owner',
field: 'pet_id'
});
return helper.dropSync([ Person, Pet ], function () {
async.parallel([
Person.create.bind(Person, { name: "John Doe" }),
Person.create.bind(Person, { name: "Jane Doe" }),
Pet.create.bind(Pet, { name: "Deco" }),
Pet.create.bind(Pet, { name: "Fido" }),
], done);
});
};
};
// Other tests...
it("should be able to find given an association instance", function (done) {
Person.find({ name: "John Doe" }).first(function (err, John) {
should.not.exist(err);
should.exist(John);
Pet.find({ name: "Deco" }).first(function (err, Deco) {
should.not.exist(err);
should.exist(Deco);
Deco.hasOwner(function (err, has_owner) {
should.not.exist(err);
has_owner.should.be.false;
Deco.setOwner(John, function (err) {
should.not.exist(err);
Person.find({ pet: Deco }).first(function (err, owner) {
should.not.exist(err);
should.exist(owner);
should.equal(owner[Person.id[0]], John[Person.id[0]]);
done();
});
});
});
});
});
});
// And 2 other tests which are variants thereof The |
Okay, I think we can mark this as resolved as of the latest code in master. We currently handle both multiple instance and multiple identifier key query generation, and haven't had any test failures as a result of the new code. If any issues are found then we'll re-open this, but in the mean time I'm gonna close it. |
Currently it is impossible to use a
find({ association: instance })
condition correctly, as such conditions are passed directly to node-sql-query without any kind of intelligent filtering.Repro
Problem
Instead of using
owner_id
, and theid
of the passed person, to run the query (as one would expect) we find node-orm2 passing the conditions in raw form to node-sql-query (not sql-query's fault, since it is supposed to be low level) which results in a SQL query like the following:What we would expect it to do is generate a SQL query like this:
Possible Solutions
The text was updated successfully, but these errors were encountered: