1 // ========================================================================== 2 // Project: The M-Project - Mobile HTML5 Application Framework 3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved. 4 // (c) 2011 panacoda GmbH. All rights reserved. 5 // Creator: Sebastian 6 // Date: 18.11.2010 7 // License: Dual licensed under the MIT or GPL Version 2 licenses. 8 // http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE 9 // http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE 10 // ========================================================================== 11 12 m_require('core/utility/logger.js'); 13 14 /** 15 * @class 16 * 17 * M.ModelAttribute encapsulates all meta information about a model record's property: 18 * * is it required? 19 * * what data type is it of? (important for mapping to relational database schemas) 20 * * what validators shall be applied 21 * All M.ModelAttributes for a model record are saved under {@link M.Model#__meta} property of a model. 22 * Each ModelAttribute is saved with the record properties name as key. 23 * That means: 24 * 25 * model.record[propA] is the value of the property. 26 * model.__meta[propA] is the {@link M.ModelAttribute} object for the record property. 27 * 28 * @extends M.Object 29 */ 30 M.ModelAttribute = M.Object.extend( 31 /** @scope M.ModelAttribute.prototype */ { 32 33 /** 34 * The type of this object. 35 * 36 * @type String 37 */ 38 type: 'M.ModelAttribute', 39 40 /** 41 * The data type for the model record property. 42 * Extremely important e.g. to map model to relational database table. 43 * 44 * @type String 45 */ 46 dataType: null, 47 48 /** 49 * Indicates whether this property is required to be set before persisting. 50 * If YES, then automatically @link M.PresenceValidator is added to the property, to check the presence. 51 * 52 * @type Boolean 53 */ 54 isRequired: NO, 55 56 /** 57 * Indicates whether an update has been performed on this property with the set method or not. 58 * @type Boolean 59 */ 60 isUpdated: NO, 61 62 /** 63 * Array containing all validators for this model record property. 64 * E.g. [@link M.PresenceValidator, @link M.NumberValidator] 65 * @type Object 66 */ 67 validators: null, 68 69 /** 70 * Record properties that define references have their referenced entity saved here. 71 * @type Object 72 */ 73 refEntity: null, 74 75 /** 76 * Iterates over validators array and calls validate on each validator with the param object passed to the validator. 77 * @param {Object} obj The parameter object containing the model id, the record as M.ModelAttribute object and the value of the property. 78 * @returns {Boolean} Indicates wheter the property is valid (YES|true) or invalid (NO|false). 79 */ 80 validate: function(obj) { 81 var isValid = YES; 82 for (var i in this.validators) { 83 if(!this.validators[i].validate(obj)) { 84 isValid = NO; 85 } 86 } 87 return isValid; 88 } 89 }); 90 91 // 92 // CLASS METHODS 93 // 94 95 /** 96 * Returns a model attribute. 97 * 98 * @param dataType The data type of the attribute: e.g. String 99 * @param opts options for the attribute, such as defaultValue, isRequired flag, etc. ... 100 * @returns {Object} {@link M.ModelAttribute} object 101 */ 102 M.ModelAttribute.attr = function(dataType, opts) { 103 //console.log('attr in model_attribute'); 104 if (!opts) { 105 opts = {}; 106 } 107 if (!opts.dataType) { 108 opts.dataType = dataType || 'String'; 109 } 110 111 /* if validators array is not set and attribute is required, define validators as an empty array, (this is for adding M.PresenceValidator automatically */ 112 if (!opts.validators && opts.isRequired) { 113 opts.validators = []; 114 } 115 116 /* if model attribute is required, presence validator is automatically inserted */ 117 if (opts.isRequired) { 118 /* check if custom presence validator has been added to validators array, if not add the presence validator*/ 119 if( _.select(opts.validators, function(v){return v.type === 'M.PresenceValidator'}).length === 0) { 120 opts.validators.push(M.PresenceValidator); 121 } 122 } 123 return this.extend(opts); 124 };