Skip to content

Commit 3064071

Browse files
committed
Allow specifying relation's name or localField in query
1 parent b190930 commit 3064071

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

src/index.js

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -294,45 +294,44 @@ class DSSqlAdapter {
294294

295295
while (parts.length >= 2) {
296296
let relationName = parts.shift()
297-
let relationResourceConfig = resourceConfig.getResource(relationName)
298-
relationPath.push(relationName)
299-
300-
if (localResourceConfig.relationList) {
301-
let [relation] = localResourceConfig.relationList.filter(r => r.relation === relationName)
302-
if (relation) {
303-
if (relation.type === 'belongsTo' || relation.type === 'hasOne') {
304-
// Apply table join for belongsTo/hasOne property (if not done already)
305-
if (!joinedTables.some(t => t === relationPath.join('.'))) {
306-
let table = getTable(localResourceConfig)
307-
let localId = `${table}.${relation.localKey}`
308-
309-
let relationTable = getTable(relationResourceConfig)
310-
let foreignId = `${relationTable}.${relationResourceConfig.idAttribute}`
311-
312-
query.join(relationTable, localId, foreignId)
313-
joinedTables.push(relationPath.join('.'))
314-
}
315-
} else if (relation.type === 'hasMany') {
316-
// Perform `WHERE EXISTS` subquery for hasMany property
297+
let [relation] = localResourceConfig.relationList.filter(r => r.relation === relationName || r.localField === relationName)
298+
299+
if (relation) {
300+
let relationResourceConfig = resourceConfig.getResource(relation.relation)
301+
relationPath.push(relation.relation)
302+
303+
if (relation.type === 'belongsTo' || relation.type === 'hasOne') {
304+
// Apply table join for belongsTo/hasOne property (if not done already)
305+
if (!joinedTables.some(t => t === relationPath.join('.'))) {
317306
let table = getTable(localResourceConfig)
318-
let localId = `${table}.${localResourceConfig.idAttribute}`
307+
let localId = `${table}.${relation.localKey}`
319308

320309
let relationTable = getTable(relationResourceConfig)
321-
let foreignId = `${relationTable}.${relation.foreignKey}`
322-
323-
let existsParams = {
324-
[foreignId]: {'===': knex.raw(localId)},
325-
[parts[0]]: criteria
326-
};
327-
query.whereExists(this.filterQuery(relationResourceConfig, existsParams, options));
328-
criteria = null; // criteria handled by EXISTS subquery
310+
let foreignId = `${relationTable}.${relationResourceConfig.idAttribute}`
311+
312+
query.join(relationTable, localId, foreignId)
313+
joinedTables.push(relationPath.join('.'))
329314
}
330-
} else {
331-
// hopefully a qualified local column
315+
} else if (relation.type === 'hasMany') {
316+
// Perform `WHERE EXISTS` subquery for hasMany property
317+
let table = getTable(localResourceConfig)
318+
let localId = `${table}.${localResourceConfig.idAttribute}`
319+
320+
let relationTable = getTable(relationResourceConfig)
321+
let foreignId = `${relationTable}.${relation.foreignKey}`
322+
323+
let existsParams = {
324+
[foreignId]: {'===': knex.raw(localId)},
325+
[parts[0]]: criteria
326+
};
327+
query.whereExists(this.filterQuery(relationResourceConfig, existsParams, options));
328+
criteria = null; // criteria handled by EXISTS subquery
332329
}
333330

334331
localResourceConfig = relationResourceConfig
335-
}
332+
} else {
333+
// hopefully a qualified local column
334+
}
336335
}
337336

338337
return `${getTable(localResourceConfig)}.${parts[0]}`

test/findAll.spec.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('DSSqlAdapter#findAll', function () {
4646
assert.equal(posts[2].content, 'baz');
4747
});
4848

49-
it('should filter using a hasMany relation', function* () {
49+
it("should filter using a hasMany relation's name", function* () {
5050
let user1 = yield adapter.create(User, {name: 'Sean'});
5151
let post1 = yield adapter.create(Post, {userId: user1.id, content: 'foo'});
5252
let post2 = yield adapter.create(Post, {userId: user1.id, content: 'bar'});
@@ -65,6 +65,26 @@ describe('DSSqlAdapter#findAll', function () {
6565
assert.equal(users[0].name, 'Sean');
6666
assert.equal(users[1].name, 'Jason');
6767
});
68+
69+
it("should filter using a hasMany relation's localField", function* () {
70+
let user1 = yield adapter.create(User, {name: 'Sean'});
71+
let post1 = yield adapter.create(Post, {userId: user1.id, content: 'foo'});
72+
let post2 = yield adapter.create(Post, {userId: user1.id, content: 'bar'});
73+
let post3 = yield adapter.create(Post, {userId: user1.id, content: 'baz'});
74+
75+
let user2 = yield adapter.create(User, {name: 'Jason'});
76+
let post4 = yield adapter.create(Post, {userId: user2.id, content: 'foo'});
77+
let post5 = yield adapter.create(Post, {userId: user2.id, content: 'bar'});
78+
79+
let user3 = yield adapter.create(User, {name: 'Ed'});
80+
let post6 = yield adapter.create(Post, {userId: user3.id, content: 'bar'});
81+
let post7 = yield adapter.create(Post, {userId: user3.id, content: 'baz'});
82+
83+
let users = yield adapter.findAll(User, {where: {'posts.content': {'==': 'foo'} }});
84+
assert.equal(users.length, 2);
85+
assert.equal(users[0].name, 'Sean');
86+
assert.equal(users[1].name, 'Jason');
87+
});
6888

6989
describe('near', function () {
7090
beforeEach(function * () {

0 commit comments

Comments
 (0)