Skip to content

Commit

Permalink
feat(hasOne): createMany and saveMany throws verbose exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jun 30, 2017
1 parent edcc890 commit c2f0b65
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 8 deletions.
20 changes: 16 additions & 4 deletions src/Exceptions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,28 @@ class InvalidArgumentException extends NE.InvalidArgumentException {
}
}

class ModelException extends RuntimeException {
class ModelException extends NE.LogicalException {
static deletedInstance (name) {
return new this(`Cannot edit deleted model instance for ${name} model`, 500, 'E_DELETED_MODEL')
}
}

class ModelNotFoundException extends RuntimeException {
class ModelNotFoundException extends NE.LogicalException {
static raise (name) {
return new this(`Cannot find database row for ${name} model`, 500, 'E_MISSING_DATABASE_ROW')
return new this(`Cannot find database row for ${name} model`, 404, 'E_MISSING_DATABASE_ROW')
}
}

module.exports = { RuntimeException, InvalidArgumentException, ModelException, ModelNotFoundException }
class ModelRelationException extends NE.LogicalException {
static unSupportedMethod (method, relation) {
return new this(`${method} is not supported by ${relation} relation`, 500, 'E_INVALID_RELATION_METHOD')
}
}

module.exports = {
RuntimeException,
InvalidArgumentException,
ModelException,
ModelNotFoundException,
ModelRelationException
}
36 changes: 32 additions & 4 deletions src/Lucid/Relations/HasOne.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

const _ = require('lodash')
const BaseRelation = require('./BaseRelation')
const CE = require('../../Exceptions')

/**
* The HasOne relationship defines a relation between
Expand Down Expand Up @@ -116,33 +117,60 @@ class HasOne extends BaseRelation {

/**
* Saves the related instance to the database. Foreign
* key is set automatically
* key is set automatically.
*
* NOTE: This method will persist the parent model if
* not persisted already.
*
* @method save
*
* @param {Object} relatedInstance
*
* @return {Promise}
*/
save (relatedInstance) {
async save (relatedInstance) {
if (this.parentInstance.isNew) {
await this.parentInstance.save()
}
relatedInstance[this.foreignKey] = this.$primaryKeyValue
return relatedInstance.save()
}

/**
* Creates the new related instance model and persist
* it to database. Foreign key is set automatically
* it to database. Foreign key is set automatically.
*
* NOTE: This method will persist the parent model if
* not persisted already.
*
* @method create
*
* @param {Object} payload
*
* @return {Promise}
*/
create (payload) {
async create (payload) {
if (this.parentInstance.isNew) {
await this.parentInstance.save()
}

payload[this.foreignKey] = this.$primaryKeyValue
return this.relatedModel.create(payload)
}

/**
* DO NOT DOCUMENT
*/
createMany () {
throw CE.ModelRelationException.unSupportedMethod('createMany', 'hasOne')
}

/**
* DO NOT DOCUMENT
*/
saveMany () {
throw CE.ModelRelationException.unSupportedMethod('saveMany', 'hasOne')
}
}

module.exports = HasOne
85 changes: 85 additions & 0 deletions test/unit/lucid-relations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1448,4 +1448,89 @@ test.group('Relations | HasOne', (group) => {
assert.equal(profile.user_id, 1)
assert.isTrue(profile.$persisted)
})

test('persist parent model if it\'s not persisted', async (assert) => {
class Profile extends Model {
}

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

Profile._bootIfNotBooted()
User._bootIfNotBooted()

const user = new User()
user.username = 'virk'
assert.isTrue(user.isNew)

const profile = new Profile()
profile.profile_name = 'virk'

await user.profile().save(profile)
assert.equal(profile.user_id, 1)
assert.isTrue(profile.$persisted)
assert.isTrue(user.$persisted)
})

test('persist parent model if it\'s not persisted via create method', async (assert) => {
class Profile extends Model {
}

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

Profile._bootIfNotBooted()
User._bootIfNotBooted()

const user = new User()
user.username = 'virk'
assert.isTrue(user.isNew)

const profile = await user.profile().create({ profile_name: 'virk' })
assert.equal(profile.user_id, 1)
assert.isTrue(profile.$persisted)
assert.isTrue(user.$persisted)
})

test('createMany with hasOne should throw exception', (assert) => {
class Profile extends Model {
}

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

Profile._bootIfNotBooted()
User._bootIfNotBooted()

const user = new User()
const fn = () => user.profile().createMany({ profile_name: 'virk' })
assert.throw(fn, 'E_INVALID_RELATION_METHOD: createMany is not supported by hasOne relation')
})

test('saveMany with hasOne should throw exception', (assert) => {
class Profile extends Model {
}

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

Profile._bootIfNotBooted()
User._bootIfNotBooted()

const user = new User()
const fn = () => user.profile().saveMany({ profile_name: 'virk' })
assert.throw(fn, 'E_INVALID_RELATION_METHOD: saveMany is not supported by hasOne relation')
})
})

0 comments on commit c2f0b65

Please sign in to comment.