all files / lib/waterline/model/ index.js

85.71% Statements 42/49
77.27% Branches 17/22
100% Functions 15/15
88.37% Lines 38/43
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135                                        280×     1182×       145×             2586×       2586×       2586× 22152×     22152× 1495×                 20657× 742× 742× 742×                                                               1277×   280×                           280×   280×     280×    
 
/**
 * Module dependencies
 */
 
var _ = require('lodash');
var Bluebird = require('bluebird');
var Model = require('./lib/model');
var defaultMethods = require('./lib/defaultMethods');
var internalMethods = require('./lib/internalMethods');
 
/**
 * Build Extended Model Prototype
 *
 * @param {Object} context
 * @param {Object} mixins
 * @return {Object}
 * @api public
 */
 
module.exports = function(context, mixins) {
 
  /**
   * Extend the model prototype with default instance methods
   */
 
  var prototypeFns = {
 
    toObject: function() {
      return new defaultMethods.toObject(context, this);
    },
 
    save: function(options, cb) {
      return new defaultMethods.save(context, this, options, cb);
    },
 
    destroy: function(cb) {
      return new defaultMethods.destroy(context, this, cb);
    },
 
    _defineAssociations: function() {
      new internalMethods.defineAssociations(context, this);
    },
 
    _normalizeAssociations: function() {
      new internalMethods.normalizeAssociations(context, this);
    },
 
    _cast: function(values) {
      _.keys(context._attributes).forEach(function(key) {
        var type = context._attributes[key].type;
 
        // Attempt to parse Array or JSON type
        if (type === 'array' || type === 'json') {
          Eif (!_.isString(values[key])) return;
          try {
            values[key] = JSON.parse(values[key]);
          } catch(e) {
            return;
          }
        }
 
        // Convert booleans back to true/false
        if (type === 'boolean') {
          var val = values[key];
          Iif (val === 0) values[key] = false;
          Iif (val === 1) values[key] = true;
        }
 
      });
    },
 
    /**
     * Model.validate()
     *
     * Takes the currently set attributes and validates the model
     * Shorthand for Model.validate({ attributes }, cb)
     *
     * @param {Function} callback - (err)
     * @return {Promise}
     */
 
    validate: function(cb) {
      // Collect current values
      var values = this.toObject();
 
      if (cb) {
        context.validate(values, function(err) {
          Eif (err) { return cb(err); }
          cb();
        });
        return;
      } else {
        return new Bluebird(function(resolve, reject) {
          context.validate(values, function(err) {
            Eif (err) { return reject(err); }
            resolve();
          });
        });
      }
    }
 
  };
 
  // If any of the attributes are protected, the default toJSON method should
  // remove them.
  var protectedAttributes = _.compact(_.map(context._attributes, function(attr, key) {return attr.protected ? key : undefined;}));
 
  prototypeFns.toJSON = function() {
    var obj = this.toObject();
 
    if (protectedAttributes.length) {
      _.each(protectedAttributes, function(key) {
        delete obj[key];
      });
    }
 
    // Remove toJSON from the result, to prevent infinite recursion with
    // msgpack or other recursive object transformation tools.
    //
    // Causes issues if set to null and will error in Sails if we delete it because blueprints call it.
    //
    // obj.toJSON = null;
 
    return obj;
  };
 
  var prototype = _.extend(prototypeFns, mixins);
 
  var model = Model.extend(prototype);
 
  // Return the extended model for use in Waterline
  return model;
};