Skip to content

Commit

Permalink
fix(eagerloading): fetch all nested relations (#273)
Browse files Browse the repository at this point in the history
* test(lucid): add test case checking for fetching nested relations

* fix(lucid): include all nested relationships

* test(lucid): add test case to check deep nested relations eager load

* refactor(lucid): replace Object.entries with _.each
  • Loading branch information
radmen authored and thetutlage committed Jan 5, 2018
1 parent 5703a7c commit 1a796cd
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 4 deletions.
7 changes: 3 additions & 4 deletions src/Lucid/EagerLoad/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,9 @@ class EagerLoad {
* @private
*/
_chainNested ({ relatedQuery }, nested) {
if (nested) {
const name = _.first(_.keys(nested))
relatedQuery.with(name, nested[name])
}
_.each(nested || {}, (callback, name) => {
relatedQuery.with(name, callback)
})
}

/**
Expand Down
86 changes: 86 additions & 0 deletions test/unit/lucid-relations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1727,4 +1727,90 @@ test.group('Relations | HasOne', (group) => {

assert.equal(userQuery.sql, helpers.formatQuery('select * from "users" where exists (select * from "profiles" where users.id = profiles.user_id and "profiles"."deleted_at" is null)'))
})

test('fetch nested relations with same root', async (assert) => {
class Car extends Model {
}

class Profile extends Model {
}

class User extends Model {
car () {
return this.hasOne(Car)
}

profile () {
return this.hasOne(Profile)
}
}

class Identity extends Model {
user () {
return this.belongsTo(User)
}
}

[Car, Profile, User, Identity].forEach(model => {
model._bootIfNotBooted()
})

await ioc.use('Database').table('users').insert({ username: 'virk' })
await ioc.use('Database').table('profiles').insert({ user_id: 1, profile_name: 'virk', likes: 3 })
await ioc.use('Database').table('cars').insert({ user_id: 1, name: 'Peugeot', model: '307' })
await ioc.use('Database').table('identities').insert({ user_id: 1, is_active: true })

const identities = await Identity.query().with('user.car').with('user.profile').fetch()
const user = identities.first().getRelated('user')

assert.exists(user.getRelated('car'))
assert.exists(user.getRelated('profile'))
})

test('fetch deep nested relations with same root', async (assert) => {
class Part extends Model {
}

class Car extends Model {
parts () {
return this.hasMany(Part)
}
}

class Profile extends Model {
}

class User extends Model {
car () {
return this.hasOne(Car)
}

profile () {
return this.hasOne(Profile)
}
}

class Identity extends Model {
user () {
return this.belongsTo(User)
}
}

[Car, Profile, User, Identity, Part].forEach(model => {
model._bootIfNotBooted()
})

await ioc.use('Database').table('users').insert({ username: 'virk' })
await ioc.use('Database').table('profiles').insert({ user_id: 1, profile_name: 'virk', likes: 3 })
await ioc.use('Database').table('cars').insert({ user_id: 1, name: 'Peugeot', model: '307' })
await ioc.use('Database').table('identities').insert({ user_id: 1, is_active: true })
await ioc.use('Database').table('parts').insert({ car_id: 1, part_name: 'Wheel drive' })

const identities = await Identity.query().with('user.car').with('user.profile').with('user.car.parts').fetch()
const user = identities.first().getRelated('user')

assert.exists(user.getRelated('car'))
assert.exists(user.getRelated('profile'))
assert.exists(user.getRelated('car').getRelated('parts').first())
})
})

0 comments on commit 1a796cd

Please sign in to comment.