/*jshint laxcomma: true, smarttabs: true, node: true, unused: true*/ 'use strict'; /** * A field for dealing with related resources * @module tastypie/fields/related * @author Eric Satterwhite * @since 0.5.0 * @requires async * @requires debug * @requires tastypie/lib/class * @requires tastypie/lib/utility * @requires tastypie/lib/fields/api */ var debug = require('debug')('tastypie:field:related') , async = require('async') , ApiField = require( './api' ) , Class = require( '../class' ) , toModule = require('../utility').toModule , RelatedField ; /** * @constructor * @alias module:tastypie/fields/related * @extends module:tastypie/fields/api * @param {Object} options * @param {String} [options.root=os.tempDir()] * @param {String} [options.dir] */ RelatedField = new Class({ inherits:ApiField ,options:{ to:null, minimal: false, full: false } ,is_related: true ,constructor: function(to, options){ if( arguments.length === 1){ options = to; to = options.to; } this.parent('constructor', options); this.options.to = to; this.instance = new this.cls(); } ,dehydrate: function( obj,cb ){ var that = this; if( !this.instance.options.apiname ){ debug('setting field %s related apiname - %s', this.options.name, this.resource.options.apiname ); this.instance.setOptions({ apiname: this.resource.options.apiname }); } this.parent('dehydrate', obj, function( err, value ){ if( err ){ return cb && cb( err, null ); } if( that.options.full ){ return cb( err, value ); } else if( that.options.minimal ){ async.map( value, that.to_minimal.bind( that ), cb ); } else{ return cb( err, value && value.map(that.instance.to_uri.bind( that.instance ) ) ); } }); } /** * converts a full object in to a minimal representation * @method module:tastypie/lib/field/related#to_minimal * @param {Object} obj A template object instance to introspect * @param {Function} callback a callback function to execute when the related field dehydration is completed **/ ,to_minimal: function( obj, cb ){ var label = this.instance.options.labelField || 'display' , that = this , related_field ; related_field = this.instance.fields[label]; related_field.dehydrate( obj, function( err, value ){ var out = {}; out.uri = that.instance.to_uri( obj ); out[ label ] = value; that = label = related_field = null; cb( null, out ); }); } }); Object.defineProperties(RelatedField.prototype,{ cls:{ enumerable:false ,writeable: false ,get: function(){ if( typeof this.options.to === 'string' ){ this.options.to = toModule( this.options.to ); } return this.options.to; } } }); module.exports = RelatedField;