UNPKG

vitamin

Version:

Data Mapper library for Node.js applications

193 lines (168 loc) 3.57 kB
import NotFoundError from './errors/model-not-found' import { extend, mapObject } from 'underscore' import BaseModel from 'vitamin-model' import Promise from 'bluebird' /** * @class Model */ export default class extends BaseModel { /** * Model constructor * * @param {Object} data * @param {Boolean} exists * @constructor */ constructor(data = {}, exists = false) { super(...arguments) this.related = {} } /** * Begin querying the model * * @return query instance */ static query() { return this.prototype.mapper.newQuery() } /** * Save a new model in the database * * @param {Object} data * @param {Array} returning * @return promise */ static create(data, returning = ['*']) { return this.make(data).save(returning) } /** * Add a listener for the given event * * @param {String} event * @param {Function} fn * @return model * @static */ static on(event, fn) { this.prototype.mapper.emitter.on(...arguments) return this } /** * Remove an event listener * * @param {String} event * @param {Function} fn * @return model * @static */ static off(event, fn) { this.prototype.mapper.emitter.off(...arguments) return this } /** * Returns a JSON representation of this model * * @return plain object */ toJSON() { var json = mapObject(this.related, (related, name) => { return (! related ) ? related : related.toJSON() }) return extend(super.toJSON(), json) } /** * Save the model in the database * * @param {Array} returning * @return promise */ save(returning = ['*']) { if (! this.isDirty() ) return Promise.resolve(this) return this.mapper.save(this, returning) } /** * Update the model in the database * * @param {Object} data * @param {Array} returning * @return promise */ update(data, returning = ['*']) { if (! this.exists ) return Promise.reject(new NotFoundError()) return this.fill(data).save(returning) } /** * Delete the model from the database * * @return promise */ destroy() { if (! this.exists ) return Promise.reject(new NotFoundError()) return this.mapper.destroy(this) } /** * Update the model's update timestamp * * @return promise */ touch() { return this.mapper.touch(this) } /** * Load the given relationships * * @param {Array} relations * @return promise */ load(relations) { return this.mapper.load([this], ...arguments).return(this) } /** * Set the relationship value in the model * * @param {String} name * @param {Any} value * @return this model */ setRelated(name, value) { this.related[name] = value return this } /** * Unset the relationship value in the model * * @param {String} name * @return this model */ unsetRelated(name) { delete this.related[name] return this } /** * Get the relationship value * * @return any */ getRelated(name) { return this.related[name] } /** * Determine if the given relationship is loaded * * @param {String} name * @return boolean */ hasRelated(name) { return !!this.related[name] } /** * Trigger an event with arguments * * @param {String} event * @param {Array} args * @return promise */ emit(event, ...args) { return this.mapper.emit(...arguments) } }