Skip to content

Commit

Permalink
fix(relation): make sure query.first eagerloads
Browse files Browse the repository at this point in the history
query().first() was not entertaining eagerloads, so fixed that
  • Loading branch information
thetutlage committed Jun 23, 2017
1 parent b87eb40 commit 7cc36c3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 35 deletions.
6 changes: 6 additions & 0 deletions src/Lucid/Model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,12 @@ class Model {
_.each(result, (values, name) => this.setRelated(name, values))
}

async loadMany (eagerLoadMap) {
const eagerLoad = new EagerLoad(eagerLoadMap)
const result = await eagerLoad.loadOne(this)
_.each(result, (values, name) => this.setRelated(name, values))
}

/**
* Returns an instance of hasOne relation
*
Expand Down
88 changes: 53 additions & 35 deletions src/Lucid/QueryBuilder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,27 @@ class QueryBuilder {
* @private
*/
_mapRowsToInstances (rows) {
return rows.map((row) => {
const modelInstance = new this.model()
modelInstance.newUp(_.omitBy(row, (value, field) => {
if (this._sideLoaded.indexOf(field) > -1) {
modelInstance.$sideLoaded[field] = value
return true
}
}))
return modelInstance
})
return rows.map((row) => this._mapRowToInstance(row))
}

/**
* Maps a single row to model instance
*
* @method _mapRowToInstance
*
* @param {Object} row
*
* @return {Model}
*/
_mapRowToInstance (row) {
const modelInstance = new this.model()
modelInstance.newUp(_.omitBy(row, (value, field) => {
if (this._sideLoaded.indexOf(field) > -1) {
modelInstance.$sideLoaded[field] = value
return true
}
}))
return modelInstance
}

/**
Expand Down Expand Up @@ -216,6 +227,38 @@ class QueryBuilder {
return new this.model.serializer(modelInstances)
}

/**
* Returns the first row from the database.
*
* @method first
*
* @return {Model|Null}
*/
async first () {
/**
* Apply all the scopes before fetching
* data
*/
this._applyScopes()

const row = await this.query.first()
if (!row) {
return null
}

const modelInstance = this._mapRowToInstance(row)

/**
* Eagerload relations when defined on query
*/
if (_.size(this._eagerLoads)) {
await modelInstance.loadMany(this._eagerLoads)
}

this.model.$hooks.after.exec('find', modelInstance)
return modelInstance
}

/**
* Paginate records, same as fetch but returns a
* collection with pagination info
Expand Down Expand Up @@ -268,31 +311,6 @@ class QueryBuilder {
return this.query.update(this.model.formatDates(values))
}

/**
* Returns the first row from the database.
*
* @method first
*
* @return {Model|Null}
*/
async first () {
/**
* Apply all the scopes before fetching
* data
*/
this._applyScopes()

const result = await this.query.first()
if (!result) {
return null
}

const modelInstance = new this.model()
modelInstance.newUp(result)
this.model.$hooks.after.exec('find', modelInstance)
return modelInstance
}

/**
* Returns an array of primaryKeys
*
Expand Down
24 changes: 24 additions & 0 deletions test/unit/lucid-relations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1202,4 +1202,28 @@ test.group('Relations | HasOne', (group) => {
assert.equal(userQuery.sql, helpers.formatQuery('select * from "users"'))
assert.equal(profileQuery.sql, helpers.formatQuery('select *, (select count(*) from "pictures" where profiles.id = pictures.profile_id) as "picture_count" from "profiles" where "user_id" in (?, ?)'))
})

test('eagerload when calling first', async (assert) => {
class Profile extends Model {
}

class User extends Model {
profile () {
return this.hasOne(Profile)
}
}

User._bootIfNotBooted()
Profile._bootIfNotBooted()

let profileQuery = null

Profile.onQuery((query) => profileQuery = query)

await ioc.use('Database').table('users').insert({ username: 'virk' })
await ioc.use('Database').table('profiles').insert({ user_id: 1, profile_name: 'virk', likes: 3 })

const user = await User.query().with('profile').first()
assert.instanceOf(user.getRelated('profile'), Profile)
})
})

0 comments on commit 7cc36c3

Please sign in to comment.