API Docs for:
Show:

File: models/server/Base.js

"use strict";

require("../../db");
var Bookshelf = require("bookshelf");
var Cocktail = require("backbone.cocktail");

var BaseMixin = require("../BaseMixin");


/**
 * Base class for server Models
 *
 * @namespace models.server
 * @extends Bookshelf.Model
 * @class Base
 * @uses models.BaseMixin
 */
var Base = Bookshelf.DB.Model.extend({

    virtuals: {

        /**
         * Unique id between tables.
         *
         * Virtual database field. Use .get("unique_id") to access it.
         *
         * @property unique_id
         * @type String
         */
        unique_id: {
            get: function() {
                if (!this.id) return;
                return this.get("type") + ":" + this.id;
            },
            // no actual database presentation
            set: function() { },
        },

        /**
         * The database table name
         *
         * Virtual database field. Use .get("type") to access it.
         *
         * @property type
         * @type String
         */
        type: {
            get: function() {
                return this.constructor.prototype.tableName;
            },
            // no actual database presentation
            set: function() { }
        }

    },

    /**
     * @method uniqueId
     * @return {String}
     */
    getUniqueId: function() {
        var type = this.tableName;
        var id = this.get("id");
        if (!id || !type) throw new Error("bad unique id");
        return type + "-" + id;
    },

    /**
     * Set timestamp to deletedAt
     *
     * @method softDelete
     * @param {models.server.User|Number} byUser The user who deleted the model
     * @return {Bluebird.Promise}
     */
    softDelete: function(byUser){
        if (!byUser) {
            throw new Error("softDelete requires a byUser argument");
        }
        this.set({
            deletedById: Base.toId(byUser),
            deletedAt: new Date(),
            deleted: this.get("id")
        });
        return this.save();
    }
}, {

    /**
     * Fetch or create a model uniquely identified by the columns defined in
     * the `identifier`
     *
     * @method fetchOrCreate
     * @param {Object} identifier Object of table columns
     * @return {Bluebird.Promise} with the model instance
     */
    fetchOrCreate: function(identifier) {
        // XXX: handle soft deleted items
        var model =  this.forge(identifier);
        return model.fetch()
        .then(function(existing) {
            return existing || model;
        });
    },

    /**
     * Shortcut for getting models by id
     *
     * @static
     * @method byId
     * @param {Number|models.server.Base} id
     * @return {models.server.Base} subclass of models.server.Base
     */
    byId: function(id) {
        return this.forge({ id: Base.toId(id) });
    },

    /**
     * Return id for the model or just return the id if the id itself is
     * passed.
     *
     * @static
     * @method toId
     * @param {Backbone.Model|any} model
     * @return {Number}
     */
    toId: function(model) {
        if (!model) throw new Error("Cannot get id for a falsy value!");
        return this.toAttr(model, "id");
    },

    /**
     * Get attribute using get() if model is Model instance or just return the
     * value
     *
     * @static
     * @method toAttr
     * @param {Backbone.Model|any} model
     * @param {String} attr Attribute to get from the model
     * @return {mixed}
     */
    toAttr: function(model, attr) {
        if (this.isModel(model)) return model.get(attr);
        return model;
    },

    /**
     * Returns true if the given value is a Backbone.Model like object
     *
     * @static
     * @method isModel
     * @param {any}
     * @return {Boolean}
     */
    isModel: function(model) {
        if (!model) return false;
        return typeof model.get === "function";
    }

});


Cocktail.mixin(Base, BaseMixin);
module.exports = Base;