Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit 9557659

Browse files
author
Dekel Barzilay
committed
Added $modifyEager query param to filter relation based on relation's field
1 parent 26e3331 commit 9557659

File tree

5 files changed

+72
-47
lines changed

5 files changed

+72
-47
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Note that all this eager related options are optional.
147147
object or array of objects with the following properties:
148148
- `expression` - the relation expression that the filter will be applied.
149149
- `filter` - the filter function. It uses
150-
[`filterEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#filtereager)
150+
[`modifyEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#modifyeager)
151151
internally.
152152
- **`namedEagerFilters`** - object containing named eager filter functions.
153153
Filter is opt-in via `$eager` parameter.
@@ -164,6 +164,8 @@ Note that all this eager related options are optional.
164164
`JoinEagerAlgorithm`. See
165165
[`$joinEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#joineager)
166166
documentation.
167+
- **`$modifyEager`** - filter relation based on a relation's field.
168+
e.g. `companies.find({ query: { $eager: 'employees', $modifyEager: { employees: { name: 'John' } } } })`
167169
- **`$pick`** - pick properties from result models. See
168170
[`pick`](https://vincit.github.io/objection.js/api/query-builder/other-methods.html#pick) documentation.
169171

package-lock.json

Lines changed: 12 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "feathers-objection",
33
"description": "A service plugin for ObjectionJS an ORM based on KnexJS",
4-
"version": "4.5.2",
4+
"version": "4.6.0",
55
"homepage": "https://github.com/feathersjs-ecosystem/feathers-objection",
66
"keywords": [
77
"feathers",

src/index.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class Service extends AdapterService {
160160
if (params.$eager) { delete params.$eager; }
161161
if (params.$joinEager) { delete params.$joinEager; }
162162
if (params.$joinRelation) { delete params.$joinRelation; }
163+
if (params.$modifyEager) { delete params.$modifyEager; }
163164
if (params.$pick) { delete params.$pick; }
164165
if (params.$noSelect) { delete params.$noSelect; }
165166

@@ -267,7 +268,6 @@ class Service extends AdapterService {
267268
}
268269

269270
// $eager for Objection eager queries
270-
271271
if (query && query.$eager) {
272272
q.eager(query.$eager, this.namedEagerFilters);
273273
delete query.$eager;
@@ -290,14 +290,23 @@ class Service extends AdapterService {
290290

291291
// apply eager filters if specified
292292
if (this.eagerFilters) {
293-
const eagerFilters = this.eagerFilters;
294-
if (Array.isArray(eagerFilters)) {
295-
for (const eagerFilter of eagerFilters) {
296-
q.filterEager(eagerFilter.expression, eagerFilter.filter);
297-
}
298-
} else {
299-
q.filterEager(eagerFilters.expression, eagerFilters.filter);
293+
const eagerFilters = Array.isArray(this.eagerFilters) ? this.eagerFilters : [this.eagerFilters];
294+
295+
for (const eagerFilter of eagerFilters) {
296+
q.modifyEager(eagerFilter.expression, eagerFilter.filter);
297+
}
298+
}
299+
300+
if (query && query.$modifyEager) {
301+
for (const eagerFilterExpression of Object.keys(query.$modifyEager)) {
302+
const eagerFilterQuery = query.$modifyEager[eagerFilterExpression];
303+
304+
q.modifyEager(eagerFilterExpression, builder => {
305+
this.objectify(builder, eagerFilterQuery);
306+
});
300307
}
308+
309+
delete query.$modifyEager;
301310
}
302311

303312
if (query && query.$pick) {

test/index.test.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ const app = feathers()
134134
model: Company,
135135
id: 'id',
136136
multi: ['create', 'remove', 'patch'],
137-
whitelist: ['$eager', '$pick', '$between', '$notBetween', '$containsKey', '$contains', '$contained', '$any', '$all', '$noSelect', '$like'],
137+
whitelist: ['$eager', '$modifyEager', '$pick', '$between', '$notBetween', '$containsKey', '$contains', '$contained', '$any', '$all', '$noSelect', '$like'],
138138
allowedEager: '[ceos, clients]',
139139
namedEagerFilters: {
140140
notSnoop (builder) {
@@ -721,26 +721,52 @@ describe('Feathers Objection Service', () => {
721721
});
722722

723723
describe('Eager queries', () => {
724-
beforeEach(async () => {
725-
const data = await people
724+
const ids = {};
725+
726+
before(async () => {
727+
ids.ceo = await people
726728
.create({
727729
name: 'Snoop',
728730
age: 20
729731
});
730732

731-
await companies
733+
ids.companies = await companies
732734
.create([
733735
{
734736
name: 'Google',
735-
ceo: data.id
737+
ceo: ids.ceo.id
736738
},
737739
{
738740
name: 'Apple',
739-
ceo: data.id
741+
ceo: ids.ceo.id
742+
}
743+
]);
744+
745+
ids.employees = await employees
746+
.create([
747+
{
748+
name: 'John',
749+
companyId: 1
750+
},
751+
{
752+
name: 'John',
753+
companyId: 1
754+
},
755+
{
756+
name: 'Dan',
757+
companyId: 1
740758
}
741759
]);
742760
});
743761

762+
after(async () => {
763+
await people.remove(ids.ceo.id);
764+
765+
for (const company of ids.companies) { await companies.remove(company.id); }
766+
767+
for (const employee of ids.employees) { await employees.remove(employee.id); }
768+
});
769+
744770
it('allows eager queries', () => {
745771
return companies.find({ query: { $eager: 'ceos' } }).then(data => {
746772
expect(data[0].ceos).to.be.ok;
@@ -753,6 +779,13 @@ describe('Feathers Objection Service', () => {
753779
});
754780
});
755781

782+
it('allows modifyEager queries', () => {
783+
return companies.find({ query: { $eager: 'employees', $modifyEager: { employees: { name: 'John' } } }, mergeAllowEager: 'employees' }).then(data => {
784+
expect(data[0].employees.length).to.equal(2);
785+
expect(data[1].employees.length).to.equal(0);
786+
});
787+
});
788+
756789
it('allows eager queries with pick', () => {
757790
return companies.find({ query: { $eager: 'ceos', $pick: ['ceos'] } }).then(data => {
758791
expect(data[0].ceos).to.be.ok;

0 commit comments

Comments
 (0)