web/res/js/backbone-relational.js
author ymh <ymh.work@gmail.com>
Fri, 15 Nov 2024 02:00:51 +0100
changeset 1579 c88b8cc7b2b8
parent 1512 487ca37bb0c7
permissions -rw-r--r--
make sending button inactive when sending
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     1
/* vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab: */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     2
/**
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
     3
 * Backbone-relational.js 0.10.0
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
     4
 * (c) 2011-2014 Paul Uithol and contributors (https://github.com/PaulUithol/Backbone-relational/graphs/contributors)
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
     5
 *
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     6
 * Backbone-relational may be freely distributed under the MIT license; see the accompanying LICENSE.txt.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     7
 * For details and documentation: https://github.com/PaulUithol/Backbone-relational.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
     8
 * Depends on Backbone (and thus on Underscore as well): https://github.com/documentcloud/backbone.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
     9
 *
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    10
 * Example:
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    11
 *
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    12
	Zoo = Backbone.RelationalModel.extend({
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    13
		relations: [ {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    14
			type: Backbone.HasMany,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    15
			key: 'animals',
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    16
			relatedModel: 'Animal',
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    17
			reverseRelation: {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    18
				key: 'livesIn',
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    19
				includeInJSON: 'id'
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    20
				// 'relatedModel' is automatically set to 'Zoo'; the 'relationType' to 'HasOne'.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    21
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    22
		} ],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    23
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    24
		toString: function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    25
			return this.get( 'name' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    26
		}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    27
	});
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    28
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    29
	Animal = Backbone.RelationalModel.extend({
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    30
		toString: function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    31
			return this.get( 'species' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    32
		}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    33
	});
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    34
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    35
	// Creating the zoo will give it a collection with one animal in it: the monkey.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    36
	// The animal created after that has a relation `livesIn` that points to the zoo it's currently associated with.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    37
	// If you instantiate (or fetch) the zebra later, it will automatically be added.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    38
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    39
	var zoo = new Zoo({
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    40
		name: 'Artis',
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    41
		animals: [ { id: 'monkey-1', species: 'Chimp' }, 'lion-1', 'zebra-1' ]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    42
	});
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    43
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    44
	var lion = new Animal( { id: 'lion-1', species: 'Lion' } ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    45
		monkey = zoo.get( 'animals' ).first(),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    46
		sameZoo = lion.get( 'livesIn' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    47
 */
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    48
( function( root, factory ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    49
	// Set up Backbone-relational for the environment. Start with AMD.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    50
	if ( typeof define === 'function' && define.amd ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    51
		define( [ 'exports', 'backbone', 'underscore' ], factory );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    52
	}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    53
	// Next for Node.js or CommonJS.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    54
	else if ( typeof exports !== 'undefined' ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    55
		factory( exports, require( 'backbone' ), require( 'underscore' ) );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    56
	}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    57
	// Finally, as a browser global. Use `root` here as it references `window`.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    58
	else {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    59
		factory( root, root.Backbone, root._ );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    60
	}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    61
}( this, function( exports, Backbone, _ ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
    62
	"use strict";
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    63
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    64
	Backbone.Relational = {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    65
		showWarnings: true
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    66
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    67
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    68
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    69
	 * Semaphore mixin; can be used as both binary and counting.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    70
	 **/
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    71
	Backbone.Semaphore = {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    72
		_permitsAvailable: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    73
		_permitsUsed: 0,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    74
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    75
		acquire: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    76
			if ( this._permitsAvailable && this._permitsUsed >= this._permitsAvailable ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    77
				throw new Error( 'Max permits acquired' );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    78
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    79
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    80
				this._permitsUsed++;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    81
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    82
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    83
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    84
		release: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    85
			if ( this._permitsUsed === 0 ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    86
				throw new Error( 'All permits released' );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    87
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    88
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    89
				this._permitsUsed--;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    90
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    91
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    92
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    93
		isLocked: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    94
			return this._permitsUsed > 0;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    95
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    96
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    97
		setAvailablePermits: function( amount ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    98
			if ( this._permitsUsed > amount ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
    99
				throw new Error( 'Available permits cannot be less than used permits' );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   100
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   101
			this._permitsAvailable = amount;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   102
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   103
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   104
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   105
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   106
	 * A BlockingQueue that accumulates items while blocked (via 'block'),
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   107
	 * and processes them when unblocked (via 'unblock').
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   108
	 * Process can also be called manually (via 'process').
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   109
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   110
	Backbone.BlockingQueue = function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   111
		this._queue = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   112
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   113
	_.extend( Backbone.BlockingQueue.prototype, Backbone.Semaphore, {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   114
		_queue: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   115
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   116
		add: function( func ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   117
			if ( this.isBlocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   118
				this._queue.push( func );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   119
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   120
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   121
				func();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   122
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   123
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   124
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   125
		// Some of the queued events may trigger other blocking events. By
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   126
		// copying the queue here it allows queued events to process closer to
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   127
		// the natural order.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   128
		//
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   129
		// queue events [ 'A', 'B', 'C' ]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   130
		// A handler of 'B' triggers 'D' and 'E'
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   131
		// By copying `this._queue` this executes:
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   132
		// [ 'A', 'B', 'D', 'E', 'C' ]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   133
		// The same order the would have executed if they didn't have to be
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   134
		// delayed and queued.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   135
		process: function() {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   136
			var queue = this._queue;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   137
			this._queue = [];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   138
			while ( queue && queue.length ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   139
				queue.shift()();
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   140
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   141
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   142
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   143
		block: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   144
			this.acquire();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   145
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   146
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   147
		unblock: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   148
			this.release();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   149
			if ( !this.isBlocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   150
				this.process();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   151
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   152
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   153
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   154
		isBlocked: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   155
			return this.isLocked();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   156
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   157
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   158
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   159
	 * Global event queue. Accumulates external events ('add:<key>', 'remove:<key>' and 'change:<key>')
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   160
	 * until the top-level object is fully initialized (see 'Backbone.RelationalModel').
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   161
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   162
	Backbone.Relational.eventQueue = new Backbone.BlockingQueue();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   163
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   164
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   165
	 * Backbone.Store keeps track of all created (and destruction of) Backbone.RelationalModel.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   166
	 * Handles lookup for relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   167
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   168
	Backbone.Store = function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   169
		this._collections = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   170
		this._reverseRelations = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   171
		this._orphanRelations = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   172
		this._subModels = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   173
		this._modelScopes = [ exports ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   174
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   175
	_.extend( Backbone.Store.prototype, Backbone.Events, {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   176
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   177
		 * Create a new `Relation`.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   178
		 * @param {Backbone.RelationalModel} [model]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   179
		 * @param {Object} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   180
		 * @param {Object} [options]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   181
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   182
		initializeRelation: function( model, relation, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   183
			var type = !_.isString( relation.type ) ? relation.type : Backbone[ relation.type ] || this.getObjectByName( relation.type );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   184
			if ( type && type.prototype instanceof Backbone.Relation ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   185
				var rel = new type( model, relation, options ); // Also pushes the new Relation into `model._relations`
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   186
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   187
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   188
				Backbone.Relational.showWarnings && typeof console !== 'undefined' && console.warn( 'Relation=%o; missing or invalid relation type!', relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   189
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   190
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   191
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   192
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   193
		 * Add a scope for `getObjectByName` to look for model types by name.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   194
		 * @param {Object} scope
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   195
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   196
		addModelScope: function( scope ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   197
			this._modelScopes.push( scope );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   198
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   199
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   200
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   201
		 * Remove a scope.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   202
		 * @param {Object} scope
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   203
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   204
		removeModelScope: function( scope ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   205
			this._modelScopes = _.without( this._modelScopes, scope );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   206
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   207
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   208
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   209
		 * Add a set of subModelTypes to the store, that can be used to resolve the '_superModel'
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   210
		 * for a model later in 'setupSuperModel'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   211
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   212
		 * @param {Backbone.RelationalModel} subModelTypes
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   213
		 * @param {Backbone.RelationalModel} superModelType
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   214
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   215
		addSubModels: function( subModelTypes, superModelType ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   216
			this._subModels.push({
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   217
				'superModelType': superModelType,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   218
				'subModels': subModelTypes
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   219
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   220
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   221
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   222
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   223
		 * Check if the given modelType is registered as another model's subModel. If so, add it to the super model's
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   224
		 * '_subModels', and set the modelType's '_superModel', '_subModelTypeName', and '_subModelTypeAttribute'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   225
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   226
		 * @param {Backbone.RelationalModel} modelType
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   227
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   228
		setupSuperModel: function( modelType ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   229
			_.find( this._subModels, function( subModelDef ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   230
				return _.filter( subModelDef.subModels || [], function( subModelTypeName, typeValue ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   231
					var subModelType = this.getObjectByName( subModelTypeName );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   232
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   233
					if ( modelType === subModelType ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   234
						// Set 'modelType' as a child of the found superModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   235
						subModelDef.superModelType._subModels[ typeValue ] = modelType;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   236
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   237
						// Set '_superModel', '_subModelTypeValue', and '_subModelTypeAttribute' on 'modelType'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   238
						modelType._superModel = subModelDef.superModelType;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   239
						modelType._subModelTypeValue = typeValue;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   240
						modelType._subModelTypeAttribute = subModelDef.superModelType.prototype.subModelTypeAttribute;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   241
						return true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   242
					}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   243
				}, this ).length;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   244
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   245
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   246
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   247
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   248
		 * Add a reverse relation. Is added to the 'relations' property on model's prototype, and to
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   249
		 * existing instances of 'model' in the store as well.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   250
		 * @param {Object} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   251
		 * @param {Backbone.RelationalModel} relation.model
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   252
		 * @param {String} relation.type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   253
		 * @param {String} relation.key
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   254
		 * @param {String|Object} relation.relatedModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   255
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   256
		addReverseRelation: function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   257
			var exists = _.any( this._reverseRelations, function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   258
				return _.all( relation || [], function( val, key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   259
					return val === rel[ key ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   260
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   261
			});
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   262
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   263
			if ( !exists && relation.model && relation.type ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   264
				this._reverseRelations.push( relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   265
				this._addRelation( relation.model, relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   266
				this.retroFitRelation( relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   267
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   268
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   269
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   270
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   271
		 * Deposit a `relation` for which the `relatedModel` can't be resolved at the moment.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   272
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   273
		 * @param {Object} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   274
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   275
		addOrphanRelation: function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   276
			var exists = _.any( this._orphanRelations, function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   277
				return _.all( relation || [], function( val, key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   278
					return val === rel[ key ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   279
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   280
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   281
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   282
			if ( !exists && relation.model && relation.type ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   283
				this._orphanRelations.push( relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   284
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   285
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   286
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   287
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   288
		 * Try to initialize any `_orphanRelation`s
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   289
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   290
		processOrphanRelations: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   291
			// Make sure to operate on a copy since we're removing while iterating
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   292
			_.each( this._orphanRelations.slice( 0 ), function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   293
				var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   294
				if ( relatedModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   295
					this.initializeRelation( null, rel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   296
					this._orphanRelations = _.without( this._orphanRelations, rel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   297
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   298
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   299
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   300
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   301
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   302
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   303
		 * @param {Backbone.RelationalModel.constructor} type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   304
		 * @param {Object} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   305
		 * @private
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   306
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   307
		_addRelation: function( type, relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   308
			if ( !type.prototype.relations ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   309
				type.prototype.relations = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   310
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   311
			type.prototype.relations.push( relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   312
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   313
			_.each( type._subModels || [], function( subModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   314
				this._addRelation( subModel, relation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   315
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   316
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   317
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   318
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   319
		 * Add a 'relation' to all existing instances of 'relation.model' in the store
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   320
		 * @param {Object} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   321
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   322
		retroFitRelation: function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   323
			var coll = this.getCollection( relation.model, false );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   324
			coll && coll.each( function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   325
				if ( !( model instanceof relation.model ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   326
					return;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   327
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   328
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   329
				var rel = new relation.type( model, relation );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   330
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   331
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   332
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   333
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   334
		 * Find the Store's collection for a certain type of model.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   335
		 * @param {Backbone.RelationalModel} type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   336
		 * @param {Boolean} [create=true] Should a collection be created if none is found?
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   337
		 * @return {Backbone.Collection} A collection if found (or applicable for 'model'), or null
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   338
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   339
		getCollection: function( type, create ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   340
			if ( type instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   341
				type = type.constructor;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   342
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   343
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   344
			var rootModel = type;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   345
			while ( rootModel._superModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   346
				rootModel = rootModel._superModel;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   347
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   348
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   349
			var coll = _.find( this._collections, function( item ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   350
				return item.model === rootModel;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   351
			});
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   352
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   353
			if ( !coll && create !== false ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   354
				coll = this._createCollection( rootModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   355
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   356
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   357
			return coll;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   358
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   359
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   360
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   361
		 * Find a model type on one of the modelScopes by name. Names are split on dots.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   362
		 * @param {String} name
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   363
		 * @return {Object}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   364
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   365
		getObjectByName: function( name ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   366
			var parts = name.split( '.' ),
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   367
				type = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   368
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   369
			_.find( this._modelScopes, function( scope ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   370
				type = _.reduce( parts || [], function( memo, val ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   371
					return memo ? memo[ val ] : undefined;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   372
				}, scope );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   373
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   374
				if ( type && type !== scope ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   375
					return true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   376
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   377
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   378
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   379
			return type;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   380
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   381
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   382
		_createCollection: function( type ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   383
			var coll;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   384
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   385
			// If 'type' is an instance, take its constructor
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   386
			if ( type instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   387
				type = type.constructor;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   388
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   389
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   390
			// Type should inherit from Backbone.RelationalModel.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   391
			if ( type.prototype instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   392
				coll = new Backbone.Collection();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   393
				coll.model = type;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   394
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   395
				this._collections.push( coll );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   396
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   397
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   398
			return coll;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   399
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   400
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   401
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   402
		 * Find the attribute that is to be used as the `id` on a given object
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   403
		 * @param type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   404
		 * @param {String|Number|Object|Backbone.RelationalModel} item
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   405
		 * @return {String|Number}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   406
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   407
		resolveIdForItem: function( type, item ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   408
			var id = _.isString( item ) || _.isNumber( item ) ? item : null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   409
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   410
			if ( id === null ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   411
				if ( item instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   412
					id = item.id;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   413
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   414
				else if ( _.isObject( item ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   415
					id = item[ type.prototype.idAttribute ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   416
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   417
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   418
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   419
			// Make all falsy values `null` (except for 0, which could be an id.. see '/issues/179')
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   420
			if ( !id && id !== 0 ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   421
				id = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   422
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   423
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   424
			return id;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   425
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   426
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   427
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   428
		 * Find a specific model of a certain `type` in the store
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   429
		 * @param type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   430
		 * @param {String|Number|Object|Backbone.RelationalModel} item
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   431
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   432
		find: function( type, item ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   433
			var id = this.resolveIdForItem( type, item ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   434
				coll = this.getCollection( type );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   435
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   436
			// Because the found object could be of any of the type's superModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   437
			// types, only return it if it's actually of the type asked for.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   438
			if ( coll ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   439
				var obj = coll.get( id );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   440
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   441
				if ( obj instanceof type ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   442
					return obj;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   443
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   444
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   445
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   446
			return null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   447
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   448
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   449
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   450
		 * Add a 'model' to its appropriate collection. Retain the original contents of 'model.collection'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   451
		 * @param {Backbone.RelationalModel} model
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   452
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   453
		register: function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   454
			var coll = this.getCollection( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   455
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   456
			if ( coll ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   457
				var modelColl = model.collection;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   458
				coll.add( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   459
				model.collection = modelColl;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   460
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   461
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   462
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   463
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   464
		 * Check if the given model may use the given `id`
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   465
		 * @param model
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   466
		 * @param [id]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   467
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   468
		checkId: function( model, id ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   469
			var coll = this.getCollection( model ),
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   470
				duplicate = coll && coll.get( id );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   471
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   472
			if ( duplicate && model !== duplicate ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   473
				if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   474
					console.warn( 'Duplicate id! Old RelationalModel=%o, new RelationalModel=%o', duplicate, model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   475
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   476
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   477
				throw new Error( "Cannot instantiate more than one Backbone.RelationalModel with the same id per type!" );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   478
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   479
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   480
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   481
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   482
		 * Explicitly update a model's id in its store collection
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   483
		 * @param {Backbone.RelationalModel} model
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   484
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   485
		update: function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   486
			var coll = this.getCollection( model );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   487
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   488
			// Register a model if it isn't yet (which happens if it was created without an id).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   489
			if ( !coll.contains( model ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   490
				this.register( model );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   491
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   492
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   493
			// This triggers updating the lookup indices kept in a collection
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   494
			coll._onModelEvent( 'change:' + model.idAttribute, model, coll );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   495
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   496
			// Trigger an event on model so related models (having the model's new id in their keyContents) can add it.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   497
			model.trigger( 'relational:change:id', model, coll );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   498
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   499
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   500
		/**
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   501
		 * Unregister from the store: a specific model, a collection, or a model type.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   502
		 * @param {Backbone.RelationalModel|Backbone.RelationalModel.constructor|Backbone.Collection} type
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   503
		 */
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   504
		unregister: function( type ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   505
			var coll,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   506
				models;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   507
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   508
			if ( type instanceof Backbone.Model ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   509
				coll = this.getCollection( type );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   510
				models = [ type ];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   511
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   512
			else if ( type instanceof Backbone.Collection ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   513
				coll = this.getCollection( type.model );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   514
				models = _.clone( type.models );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   515
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   516
			else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   517
				coll = this.getCollection( type );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   518
				models = _.clone( coll.models );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   519
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   520
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   521
			_.each( models, function( model ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   522
				this.stopListening( model );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   523
				_.invoke( model.getRelations(), 'stopListening' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   524
			}, this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   525
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   526
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   527
			// If we've unregistered an entire store collection, reset the collection (which is much faster).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   528
			// Otherwise, remove each model one by one.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   529
			if ( _.contains( this._collections, type ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   530
				coll.reset( [] );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   531
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   532
			else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   533
				_.each( models, function( model ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   534
					if ( coll.get( model ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   535
						coll.remove( model );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   536
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   537
					else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   538
						coll.trigger( 'relational:remove', model, coll );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   539
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   540
				}, this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   541
			}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   542
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   543
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   544
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   545
		 * Reset the `store` to it's original state. The `reverseRelations` are kept though, since attempting to
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   546
		 * re-initialize these on models would lead to a large amount of warnings.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   547
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   548
		reset: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   549
			this.stopListening();
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   550
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   551
			// Unregister each collection to remove event listeners
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   552
			_.each( this._collections, function( coll ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   553
				this.unregister( coll );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   554
			}, this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   555
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   556
			this._collections = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   557
			this._subModels = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   558
			this._modelScopes = [ exports ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   559
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   560
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   561
	Backbone.Relational.store = new Backbone.Store();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   562
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   563
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   564
	 * The main Relation class, from which 'HasOne' and 'HasMany' inherit. Internally, 'relational:<key>' events
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   565
	 * are used to regulate addition and removal of models from relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   566
	 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   567
	 * @param {Backbone.RelationalModel} [instance] Model that this relation is created for. If no model is supplied,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   568
	 *      Relation just tries to instantiate it's `reverseRelation` if specified, and bails out after that.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   569
	 * @param {Object} options
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   570
	 * @param {string} options.key
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   571
	 * @param {Backbone.RelationalModel.constructor} options.relatedModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   572
	 * @param {Boolean|String} [options.includeInJSON=true] Serialize the given attribute for related model(s)' in toJSON, or just their ids.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   573
	 * @param {Boolean} [options.createModels=true] Create objects from the contents of keys if the object is not found in Backbone.store.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   574
	 * @param {Object} [options.reverseRelation] Specify a bi-directional relation. If provided, Relation will reciprocate
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   575
	 *    the relation to the 'relatedModel'. Required and optional properties match 'options', except that it also needs
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   576
	 *    {Backbone.Relation|String} type ('HasOne' or 'HasMany').
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   577
	 * @param {Object} opts
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   578
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   579
	Backbone.Relation = function( instance, options, opts ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   580
		this.instance = instance;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   581
		// Make sure 'options' is sane, and fill with defaults from subclasses and this object's prototype
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   582
		options = _.isObject( options ) ? options : {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   583
		this.reverseRelation = _.defaults( options.reverseRelation || {}, this.options.reverseRelation );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   584
		this.options = _.defaults( options, this.options, Backbone.Relation.prototype.options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   585
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   586
		this.reverseRelation.type = !_.isString( this.reverseRelation.type ) ? this.reverseRelation.type :
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   587
			Backbone[ this.reverseRelation.type ] || Backbone.Relational.store.getObjectByName( this.reverseRelation.type );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   588
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   589
		this.key = this.options.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   590
		this.keySource = this.options.keySource || this.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   591
		this.keyDestination = this.options.keyDestination || this.keySource || this.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   592
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   593
		this.model = this.options.model || this.instance.constructor;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   594
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   595
		this.relatedModel = this.options.relatedModel;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   596
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   597
		// No 'relatedModel' is interpreted as self-referential
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   598
		if ( _.isUndefined( this.relatedModel ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   599
			this.relatedModel = this.model;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   600
		}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   601
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   602
		// Otherwise, try to resolve the given value to an object
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   603
		if ( _.isFunction( this.relatedModel ) && !( this.relatedModel.prototype instanceof Backbone.RelationalModel ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   604
			this.relatedModel = _.result( this, 'relatedModel' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   605
		}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   606
		if ( _.isString( this.relatedModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   607
			this.relatedModel = Backbone.Relational.store.getObjectByName( this.relatedModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   608
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   609
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   610
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   611
		if ( !this.checkPreconditions() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   612
			return;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   613
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   614
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   615
		// Add the reverse relation on 'relatedModel' to the store's reverseRelations
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   616
		if ( !this.options.isAutoRelation && this.reverseRelation.type && this.reverseRelation.key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   617
			Backbone.Relational.store.addReverseRelation( _.defaults( {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   618
					isAutoRelation: true,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   619
					model: this.relatedModel,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   620
					relatedModel: this.model,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   621
					reverseRelation: this.options // current relation is the 'reverseRelation' for its own reverseRelation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   622
				},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   623
				this.reverseRelation // Take further properties from this.reverseRelation (type, key, etc.)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   624
			) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   625
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   626
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   627
		if ( instance ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   628
			var contentKey = this.keySource;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   629
			if ( contentKey !== this.key && _.isObject( this.instance.get( this.key ) ) ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   630
				contentKey = this.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   631
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   632
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   633
			this.setKeyContents( this.instance.get( contentKey ) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   634
			this.relatedCollection = Backbone.Relational.store.getCollection( this.relatedModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   635
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   636
			// Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   637
			if ( this.keySource !== this.key ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   638
				delete this.instance.attributes[ this.keySource ];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   639
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   640
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   641
			// Add this Relation to instance._relations
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   642
			this.instance._relations[ this.key ] = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   643
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   644
			this.initialize( opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   645
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   646
			if ( this.options.autoFetch ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   647
				this.instance.getAsync( this.key, _.isObject( this.options.autoFetch ) ? this.options.autoFetch : {} );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   648
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   649
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   650
			// When 'relatedModel' are created or destroyed, check if it affects this relation.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   651
			this.listenTo( this.instance, 'destroy', this.destroy )
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   652
				.listenTo( this.relatedCollection, 'relational:add relational:change:id', this.tryAddRelated )
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   653
				.listenTo( this.relatedCollection, 'relational:remove', this.removeRelated );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   654
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   655
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   656
	// Fix inheritance :\
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   657
	Backbone.Relation.extend = Backbone.Model.extend;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   658
	// Set up all inheritable **Backbone.Relation** properties and methods.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   659
	_.extend( Backbone.Relation.prototype, Backbone.Events, Backbone.Semaphore, {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   660
		options: {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   661
			createModels: true,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   662
			includeInJSON: true,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   663
			isAutoRelation: false,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   664
			autoFetch: false,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   665
			parse: false
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   666
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   667
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   668
		instance: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   669
		key: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   670
		keyContents: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   671
		relatedModel: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   672
		relatedCollection: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   673
		reverseRelation: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   674
		related: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   675
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   676
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   677
		 * Check several pre-conditions.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   678
		 * @return {Boolean} True if pre-conditions are satisfied, false if they're not.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   679
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   680
		checkPreconditions: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   681
			var i = this.instance,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   682
				k = this.key,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   683
				m = this.model,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   684
				rm = this.relatedModel,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   685
				warn = Backbone.Relational.showWarnings && typeof console !== 'undefined';
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   686
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   687
			if ( !m || !k || !rm ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   688
				warn && console.warn( 'Relation=%o: missing model, key or relatedModel (%o, %o, %o).', this, m, k, rm );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   689
				return false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   690
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   691
			// Check if the type in 'model' inherits from Backbone.RelationalModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   692
			if ( !( m.prototype instanceof Backbone.RelationalModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   693
				warn && console.warn( 'Relation=%o: model does not inherit from Backbone.RelationalModel (%o).', this, i );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   694
				return false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   695
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   696
			// Check if the type in 'relatedModel' inherits from Backbone.RelationalModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   697
			if ( !( rm.prototype instanceof Backbone.RelationalModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   698
				warn && console.warn( 'Relation=%o: relatedModel does not inherit from Backbone.RelationalModel (%o).', this, rm );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   699
				return false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   700
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   701
			// Check if this is not a HasMany, and the reverse relation is HasMany as well
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   702
			if ( this instanceof Backbone.HasMany && this.reverseRelation.type === Backbone.HasMany ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   703
				warn && console.warn( 'Relation=%o: relation is a HasMany, and the reverseRelation is HasMany as well.', this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   704
				return false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   705
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   706
			// Check if we're not attempting to create a relationship on a `key` that's already used.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   707
			if ( i && _.keys( i._relations ).length ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   708
				var existing = _.find( i._relations, function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   709
					return rel.key === k;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   710
				}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   711
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   712
				if ( existing ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   713
					warn && console.warn( 'Cannot create relation=%o on %o for model=%o: already taken by relation=%o.',
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   714
						this, k, i, existing );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   715
					return false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   716
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   717
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   718
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   719
			return true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   720
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   721
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   722
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   723
		 * Set the related model(s) for this relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   724
		 * @param {Backbone.Model|Backbone.Collection} related
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   725
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   726
		setRelated: function( related ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   727
			this.related = related;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   728
			this.instance.attributes[ this.key ] = related;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   729
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   730
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   731
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   732
		 * Determine if a relation (on a different RelationalModel) is the reverse
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   733
		 * relation of the current one.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   734
		 * @param {Backbone.Relation} relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   735
		 * @return {Boolean}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   736
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   737
		_isReverseRelation: function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   738
			return relation.instance instanceof this.relatedModel && this.reverseRelation.key === relation.key &&
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   739
				this.key === relation.reverseRelation.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   740
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   741
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   742
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   743
		 * Get the reverse relations (pointing back to 'this.key' on 'this.instance') for the currently related model(s).
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   744
		 * @param {Backbone.RelationalModel} [model] Get the reverse relations for a specific model.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   745
		 *    If not specified, 'this.related' is used.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   746
		 * @return {Backbone.Relation[]}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   747
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   748
		getReverseRelations: function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   749
			var reverseRelations = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   750
			// Iterate over 'model', 'this.related.models' (if this.related is a Backbone.Collection), or wrap 'this.related' in an array.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   751
			var models = !_.isUndefined( model ) ? [ model ] : this.related && ( this.related.models || [ this.related ] ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   752
				relations = null,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   753
				relation = null;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   754
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   755
			for( var i = 0; i < ( models || [] ).length; i++ ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   756
				relations = models[ i ].getRelations() || [];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   757
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   758
				for( var j = 0; j < relations.length; j++ ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   759
					relation = relations[ j ];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   760
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   761
					if ( this._isReverseRelation( relation ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   762
						reverseRelations.push( relation );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   763
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   764
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   765
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   766
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   767
			return reverseRelations;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   768
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   769
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   770
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   771
		 * When `this.instance` is destroyed, cleanup our relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   772
		 * Get reverse relation, call removeRelated on each.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   773
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   774
		destroy: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   775
			this.stopListening();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   776
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   777
			if ( this instanceof Backbone.HasOne ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   778
				this.setRelated( null );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   779
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   780
			else if ( this instanceof Backbone.HasMany ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   781
				this.setRelated( this._prepareCollection() );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   782
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   783
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   784
			_.each( this.getReverseRelations(), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   785
				relation.removeRelated( this.instance );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   786
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   787
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   788
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   789
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   790
	Backbone.HasOne = Backbone.Relation.extend({
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   791
		options: {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   792
			reverseRelation: { type: 'HasMany' }
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   793
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   794
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   795
		initialize: function( opts ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   796
			this.listenTo( this.instance, 'relational:change:' + this.key, this.onChange );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   797
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   798
			var related = this.findRelated( opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   799
			this.setRelated( related );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   800
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   801
			// Notify new 'related' object of the new relation.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   802
			_.each( this.getReverseRelations(), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   803
				relation.addRelated( this.instance, opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   804
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   805
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   806
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   807
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   808
		 * Find related Models.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   809
		 * @param {Object} [options]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   810
		 * @return {Backbone.Model}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   811
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   812
		findRelated: function( options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   813
			var related = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   814
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   815
			options = _.defaults( { parse: this.options.parse }, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   816
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   817
			if ( this.keyContents instanceof this.relatedModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   818
				related = this.keyContents;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   819
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   820
			else if ( this.keyContents || this.keyContents === 0 ) { // since 0 can be a valid `id` as well
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   821
				var opts = _.defaults( { create: this.options.createModels }, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   822
				related = this.relatedModel.findOrCreate( this.keyContents, opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   823
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   824
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   825
			// Nullify `keyId` if we have a related model; in case it was already part of the relation
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   826
			if ( related ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   827
				this.keyId = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   828
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   829
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   830
			return related;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   831
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   832
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   833
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   834
		 * Normalize and reduce `keyContents` to an `id`, for easier comparison
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   835
		 * @param {String|Number|Backbone.Model} keyContents
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   836
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   837
		setKeyContents: function( keyContents ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   838
			this.keyContents = keyContents;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   839
			this.keyId = Backbone.Relational.store.resolveIdForItem( this.relatedModel, this.keyContents );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   840
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   841
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   842
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   843
		 * Event handler for `change:<key>`.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   844
		 * If the key is changed, notify old & new reverse relations and initialize the new relation.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   845
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   846
		onChange: function( model, attr, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   847
			// Don't accept recursive calls to onChange (like onChange->findRelated->findOrCreate->initializeRelations->addRelated->onChange)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   848
			if ( this.isLocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   849
				return;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   850
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   851
			this.acquire();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   852
			options = options ? _.clone( options ) : {};
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   853
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   854
			// 'options.__related' is set by 'addRelated'/'removeRelated'. If it is set, the change
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   855
			// is the result of a call from a relation. If it's not, the change is the result of
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   856
			// a 'set' call on this.instance.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   857
			var changed = _.isUndefined( options.__related ),
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   858
				oldRelated = changed ? this.related : options.__related;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   859
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   860
			if ( changed ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   861
				this.setKeyContents( attr );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   862
				var related = this.findRelated( options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   863
				this.setRelated( related );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   864
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   865
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   866
			// Notify old 'related' object of the terminated relation
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   867
			if ( oldRelated && this.related !== oldRelated ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   868
				_.each( this.getReverseRelations( oldRelated ), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   869
					relation.removeRelated( this.instance, null, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   870
				}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   871
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   873
			// Notify new 'related' object of the new relation. Note we do re-apply even if this.related is oldRelated;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   874
			// that can be necessary for bi-directional relations if 'this.instance' was created after 'this.related'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   875
			// In that case, 'this.instance' will already know 'this.related', but the reverse might not exist yet.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   876
			_.each( this.getReverseRelations(), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   877
				relation.addRelated( this.instance, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   878
			}, this );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   879
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   880
			// Fire the 'change:<key>' event if 'related' was updated
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   881
			if ( !options.silent && this.related !== oldRelated ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   882
				var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   883
				this.changed = true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   884
				Backbone.Relational.eventQueue.add( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   885
					dit.instance.trigger( 'change:' + dit.key, dit.instance, dit.related, options, true );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   886
					dit.changed = false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   887
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   888
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   889
			this.release();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   890
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   891
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   892
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   893
		 * If a new 'this.relatedModel' appears in the 'store', try to match it to the last set 'keyContents'
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   894
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   895
		tryAddRelated: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   896
			if ( ( this.keyId || this.keyId === 0 ) && model.id === this.keyId ) { // since 0 can be a valid `id` as well
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   897
				this.addRelated( model, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   898
				this.keyId = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   899
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   900
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   901
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   902
		addRelated: function( model, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   903
			// Allow 'model' to set up its relations before proceeding.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   904
			// (which can result in a call to 'addRelated' from a relation of 'model')
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   905
			var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   906
			model.queue( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   907
				if ( model !== dit.related ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   908
					var oldRelated = dit.related || null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   909
					dit.setRelated( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   910
					dit.onChange( dit.instance, model, _.defaults( { __related: oldRelated }, options ) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   911
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   912
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   913
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   914
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   915
		removeRelated: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   916
			if ( !this.related ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   917
				return;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   918
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   919
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   920
			if ( model === this.related ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   921
				var oldRelated = this.related || null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   922
				this.setRelated( null );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   923
				this.onChange( this.instance, model, _.defaults( { __related: oldRelated }, options ) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   924
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   925
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   926
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   927
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   928
	Backbone.HasMany = Backbone.Relation.extend({
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   929
		collectionType: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   930
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   931
		options: {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   932
			reverseRelation: { type: 'HasOne' },
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   933
			collectionType: Backbone.Collection,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   934
			collectionKey: true,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   935
			collectionOptions: {}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   936
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   937
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   938
		initialize: function( opts ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   939
			this.listenTo( this.instance, 'relational:change:' + this.key, this.onChange );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   940
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   941
			// Handle a custom 'collectionType'
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   942
			this.collectionType = this.options.collectionType;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   943
			if ( _.isFunction( this.collectionType ) && this.collectionType !== Backbone.Collection && !( this.collectionType.prototype instanceof Backbone.Collection ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   944
				this.collectionType = _.result( this, 'collectionType' );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   945
			}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   946
			if ( _.isString( this.collectionType ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   947
				this.collectionType = Backbone.Relational.store.getObjectByName( this.collectionType );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   948
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   949
			if ( this.collectionType !== Backbone.Collection && !( this.collectionType.prototype instanceof Backbone.Collection ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   950
				throw new Error( '`collectionType` must inherit from Backbone.Collection' );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   951
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   952
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   953
			var related = this.findRelated( opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   954
			this.setRelated( related );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   955
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   956
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   957
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   958
		 * Bind events and setup collectionKeys for a collection that is to be used as the backing store for a HasMany.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   959
		 * If no 'collection' is supplied, a new collection will be created of the specified 'collectionType' option.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   960
		 * @param {Backbone.Collection} [collection]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   961
		 * @return {Backbone.Collection}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   962
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   963
		_prepareCollection: function( collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   964
			if ( this.related ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   965
				this.stopListening( this.related );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   966
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   967
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   968
			if ( !collection || !( collection instanceof Backbone.Collection ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   969
				var options = _.isFunction( this.options.collectionOptions ) ?
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   970
					this.options.collectionOptions( this.instance ) : this.options.collectionOptions;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   971
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   972
				collection = new this.collectionType( null, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   973
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   974
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   975
			collection.model = this.relatedModel;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   976
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   977
			if ( this.options.collectionKey ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   978
				var key = this.options.collectionKey === true ? this.options.reverseRelation.key : this.options.collectionKey;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   979
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   980
				if ( collection[ key ] && collection[ key ] !== this.instance ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   981
					if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   982
						console.warn( 'Relation=%o; collectionKey=%s already exists on collection=%o', this, key, this.options.collectionKey );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   983
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   984
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   985
				else if ( key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   986
					collection[ key ] = this.instance;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   987
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   988
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   989
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   990
			this.listenTo( collection, 'relational:add', this.handleAddition )
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   991
				.listenTo( collection, 'relational:remove', this.handleRemoval )
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   992
				.listenTo( collection, 'relational:reset', this.handleReset );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
   993
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   994
			return collection;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   995
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   996
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   997
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   998
		 * Find related Models.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
   999
		 * @param {Object} [options]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1000
		 * @return {Backbone.Collection}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1001
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1002
		findRelated: function( options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1003
			var related = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1004
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1005
			options = _.defaults( { parse: this.options.parse }, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1006
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1007
			// Replace 'this.related' by 'this.keyContents' if it is a Backbone.Collection
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1008
			if ( this.keyContents instanceof Backbone.Collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1009
				this._prepareCollection( this.keyContents );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1010
				related = this.keyContents;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1011
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1012
			// Otherwise, 'this.keyContents' should be an array of related object ids.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1013
			// Re-use the current 'this.related' if it is a Backbone.Collection; otherwise, create a new collection.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1014
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1015
				var toAdd = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1016
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1017
				_.each( this.keyContents, function( attributes ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1018
					var model = null;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1019
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1020
					if ( attributes instanceof this.relatedModel ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1021
						model = attributes;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1022
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1023
					else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1024
						// If `merge` is true, update models here, instead of during update.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1025
						model = ( _.isObject( attributes ) && options.parse && this.relatedModel.prototype.parse ) ?
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1026
							this.relatedModel.prototype.parse( _.clone( attributes ), options ) : attributes;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1027
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1028
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1029
					model && toAdd.push( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1030
				}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1031
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1032
				if ( this.related instanceof Backbone.Collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1033
					related = this.related;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1034
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1035
				else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1036
					related = this._prepareCollection();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1037
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1038
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1039
				// By now, `parse` will already have been executed just above for models if specified.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1040
				// Disable to prevent additional calls.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1041
				related.set( toAdd, _.defaults( { parse: false }, options ) );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1042
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1043
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1044
			// Remove entries from `keyIds` that were already part of the relation (and are thus 'unchanged')
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1045
			this.keyIds = _.difference( this.keyIds, _.pluck( related.models, 'id' ) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1046
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1047
			return related;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1048
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1049
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1050
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1051
		 * Normalize and reduce `keyContents` to a list of `ids`, for easier comparison
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1052
		 * @param {String|Number|String[]|Number[]|Backbone.Collection} keyContents
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1053
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1054
		setKeyContents: function( keyContents ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1055
			this.keyContents = keyContents instanceof Backbone.Collection ? keyContents : null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1056
			this.keyIds = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1057
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1058
			if ( !this.keyContents && ( keyContents || keyContents === 0 ) ) { // since 0 can be a valid `id` as well
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1059
				// Handle cases the an API/user supplies just an Object/id instead of an Array
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1060
				this.keyContents = _.isArray( keyContents ) ? keyContents : [ keyContents ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1061
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1062
				_.each( this.keyContents, function( item ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1063
					var itemId = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1064
					if ( itemId || itemId === 0 ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1065
						this.keyIds.push( itemId );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1066
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1067
				}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1068
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1069
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1070
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1071
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1072
		 * Event handler for `change:<key>`.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1073
		 * If the contents of the key are changed, notify old & new reverse relations and initialize the new relation.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1074
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1075
		onChange: function( model, attr, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1076
			options = options ? _.clone( options ) : {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1077
			this.setKeyContents( attr );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1078
			this.changed = false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1079
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1080
			var related = this.findRelated( options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1081
			this.setRelated( related );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1082
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1083
			if ( !options.silent ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1084
				var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1085
				Backbone.Relational.eventQueue.add( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1086
					// The `changed` flag can be set in `handleAddition` or `handleRemoval`
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1087
					if ( dit.changed ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1088
						dit.instance.trigger( 'change:' + dit.key, dit.instance, dit.related, options, true );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1089
						dit.changed = false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1090
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1091
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1092
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1093
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1094
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1095
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1096
		 * When a model is added to a 'HasMany', trigger 'add' on 'this.instance' and notify reverse relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1097
		 * (should be 'HasOne', must set 'this.instance' as their related).
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1098
		 */
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1099
		handleAddition: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1100
			//console.debug('handleAddition called; args=%o', arguments);
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1101
			options = options ? _.clone( options ) : {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1102
			this.changed = true;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1103
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1104
			_.each( this.getReverseRelations( model ), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1105
				relation.addRelated( this.instance, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1106
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1107
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1108
			// Only trigger 'add' once the newly added model is initialized (so, has its relations set up)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1109
			var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1110
			!options.silent && Backbone.Relational.eventQueue.add( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1111
				dit.instance.trigger( 'add:' + dit.key, model, dit.related, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1112
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1113
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1114
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1115
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1116
		 * When a model is removed from a 'HasMany', trigger 'remove' on 'this.instance' and notify reverse relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1117
		 * (should be 'HasOne', which should be nullified)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1118
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1119
		handleRemoval: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1120
			//console.debug('handleRemoval called; args=%o', arguments);
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1121
			options = options ? _.clone( options ) : {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1122
			this.changed = true;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1123
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1124
			_.each( this.getReverseRelations( model ), function( relation ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1125
				relation.removeRelated( this.instance, null, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1126
			}, this );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1127
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1128
			var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1129
			!options.silent && Backbone.Relational.eventQueue.add( function() {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1130
				dit.instance.trigger( 'remove:' + dit.key, model, dit.related, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1131
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1132
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1133
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1134
		handleReset: function( coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1135
			var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1136
			options = options ? _.clone( options ) : {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1137
			!options.silent && Backbone.Relational.eventQueue.add( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1138
				dit.instance.trigger( 'reset:' + dit.key, dit.related, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1139
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1140
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1141
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1142
		tryAddRelated: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1143
			var item = _.contains( this.keyIds, model.id );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1144
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1145
			if ( item ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1146
				this.addRelated( model, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1147
				this.keyIds = _.without( this.keyIds, model.id );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1148
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1149
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1150
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1151
		addRelated: function( model, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1152
			// Allow 'model' to set up its relations before proceeding.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1153
			// (which can result in a call to 'addRelated' from a relation of 'model')
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1154
			var dit = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1155
			model.queue( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1156
				if ( dit.related && !dit.related.get( model ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1157
					dit.related.add( model, _.defaults( { parse: false }, options ) );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1158
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1159
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1160
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1161
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1162
		removeRelated: function( model, coll, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1163
			if ( this.related.get( model ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1164
				this.related.remove( model, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1165
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1166
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1167
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1168
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1169
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1170
	 * A type of Backbone.Model that also maintains relations to other models and collections.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1171
	 * New events when compared to the original:
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1172
	 *  - 'add:<key>' (model, related collection, options)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1173
	 *  - 'remove:<key>' (model, related collection, options)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1174
	 *  - 'change:<key>' (model, related model or collection, options)
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1175
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1176
	Backbone.RelationalModel = Backbone.Model.extend({
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1177
		relations: null, // Relation descriptions on the prototype
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1178
		_relations: null, // Relation instances
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1179
		_isInitialized: false,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1180
		_deferProcessing: false,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1181
		_queue: null,
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1182
		_attributeChangeFired: false, // Keeps track of `change` event firing under some conditions (like nested `set`s)
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1183
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1184
		subModelTypeAttribute: 'type',
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1185
		subModelTypes: null,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1186
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1187
		constructor: function( attributes, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1188
			// Nasty hack, for cases like 'model.get( <HasMany key> ).add( item )'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1189
			// Defer 'processQueue', so that when 'Relation.createModels' is used we trigger 'HasMany'
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1190
			// collection events only after the model is really fully set up.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1191
			// Example: event for "p.on( 'add:jobs' )" -> "p.get('jobs').add( { company: c.id, person: p.id } )".
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1192
			if ( options && options.collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1193
				var dit = this,
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1194
					collection = this.collection = options.collection;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1195
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1196
				// Prevent `collection` from cascading down to nested models; they shouldn't go into this `if` clause.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1197
				delete options.collection;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1198
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1199
				this._deferProcessing = true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1200
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1201
				var processQueue = function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1202
					if ( model === dit ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1203
						dit._deferProcessing = false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1204
						dit.processQueue();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1205
						collection.off( 'relational:add', processQueue );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1206
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1207
				};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1208
				collection.on( 'relational:add', processQueue );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1209
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1210
				// So we do process the queue eventually, regardless of whether this model actually gets added to 'options.collection'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1211
				_.defer( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1212
					processQueue( dit );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1213
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1214
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1215
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1216
			Backbone.Relational.store.processOrphanRelations();
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1217
			Backbone.Relational.store.listenTo( this, 'relational:unregister', Backbone.Relational.store.unregister );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1218
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1219
			this._queue = new Backbone.BlockingQueue();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1220
			this._queue.block();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1221
			Backbone.Relational.eventQueue.block();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1222
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1223
			try {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1224
				Backbone.Model.apply( this, arguments );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1225
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1226
			finally {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1227
				// Try to run the global queue holding external events
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1228
				Backbone.Relational.eventQueue.unblock();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1229
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1230
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1231
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1232
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1233
		 * Override 'trigger' to queue 'change' and 'change:*' events
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1234
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1235
		trigger: function( eventName ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1236
			if ( eventName.length > 5 && eventName.indexOf( 'change' ) === 0 ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1237
				var dit = this,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1238
					args = arguments;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1239
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1240
				if ( !Backbone.Relational.eventQueue.isBlocked() ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1241
					// If we're not in a more complicated nested scenario, fire the change event right away
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1242
					Backbone.Model.prototype.trigger.apply( dit, args );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1243
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1244
				else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1245
					Backbone.Relational.eventQueue.add( function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1246
						// Determine if the `change` event is still valid, now that all relations are populated
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1247
						var changed = true;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1248
						if ( eventName === 'change' ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1249
							// `hasChanged` may have gotten reset by nested calls to `set`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1250
							changed = dit.hasChanged() || dit._attributeChangeFired;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1251
							dit._attributeChangeFired = false;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1252
						}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1253
						else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1254
							var attr = eventName.slice( 7 ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1255
								rel = dit.getRelation( attr );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1256
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1257
							if ( rel ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1258
								// If `attr` is a relation, `change:attr` get triggered from `Relation.onChange`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1259
								// These take precedence over `change:attr` events triggered by `Model.set`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1260
								// The relation sets a fourth attribute to `true`. If this attribute is present,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1261
								// continue triggering this event; otherwise, it's from `Model.set` and should be stopped.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1262
								changed = ( args[ 4 ] === true );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1263
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1264
								// If this event was triggered by a relation, set the right value in `this.changed`
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1265
								// (a Collection or Model instead of raw data).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1266
								if ( changed ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1267
									dit.changed[ attr ] = args[ 2 ];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1268
								}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1269
								// Otherwise, this event is from `Model.set`. If the relation doesn't report a change,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1270
								// remove attr from `dit.changed` so `hasChanged` doesn't take it into account.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1271
								else if ( !rel.changed ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1272
									delete dit.changed[ attr ];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1273
								}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1274
							}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1275
							else if ( changed ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1276
								dit._attributeChangeFired = true;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1277
							}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1278
						}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1279
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1280
						changed && Backbone.Model.prototype.trigger.apply( dit, args );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1281
					});
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1282
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1283
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1284
			else if ( eventName === 'destroy' ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1285
				Backbone.Model.prototype.trigger.apply( this, arguments );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1286
				Backbone.Relational.store.unregister( this );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1287
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1288
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1289
				Backbone.Model.prototype.trigger.apply( this, arguments );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1290
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1291
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1292
			return this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1293
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1294
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1295
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1296
		 * Initialize Relations present in this.relations; determine the type (HasOne/HasMany), then creates a new instance.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1297
		 * Invoked in the first call so 'set' (which is made from the Backbone.Model constructor).
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1298
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1299
		initializeRelations: function( options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1300
			this.acquire(); // Setting up relations often also involve calls to 'set', and we only want to enter this function once
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1301
			this._relations = {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1302
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1303
			_.each( this.relations || [], function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1304
				Backbone.Relational.store.initializeRelation( this, rel, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1305
			}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1306
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1307
			this._isInitialized = true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1308
			this.release();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1309
			this.processQueue();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1310
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1311
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1312
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1313
		 * When new values are set, notify this model's relations (also if options.silent is set).
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1314
		 * (called from `set`; Relation.setRelated locks this model before calling 'set' on it to prevent loops)
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1315
		 * @param {Object} [changedAttrs]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1316
		 * @param {Object} [options]
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1317
		 */
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1318
		updateRelations: function( changedAttrs, options ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1319
			if ( this._isInitialized && !this.isLocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1320
				_.each( this._relations, function( rel ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1321
					if ( !changedAttrs || ( rel.keySource in changedAttrs || rel.key in changedAttrs ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1322
						// Fetch data in `rel.keySource` if data got set in there, or `rel.key` otherwise
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1323
						var value = this.attributes[ rel.keySource ] || this.attributes[ rel.key ],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1324
							attr = changedAttrs && ( changedAttrs[ rel.keySource ] || changedAttrs[ rel.key ] );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1325
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1326
						// Update a relation if its value differs from this model's attributes, or it's been explicitly nullified.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1327
						// Which can also happen before the originally intended related model has been found (`val` is null).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1328
						if ( rel.related !== value || ( value === null && attr === null ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1329
							this.trigger( 'relational:change:' + rel.key, this, value, options || {} );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1330
						}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1331
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1332
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1333
					// Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1334
					if ( rel.keySource !== rel.key ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1335
						delete this.attributes[ rel.keySource ];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1336
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1337
				}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1338
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1339
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1340
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1341
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1342
		 * Either add to the queue (if we're not initialized yet), or execute right away.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1343
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1344
		queue: function( func ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1345
			this._queue.add( func );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1346
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1347
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1348
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1349
		 * Process _queue
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1350
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1351
		processQueue: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1352
			if ( this._isInitialized && !this._deferProcessing && this._queue.isBlocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1353
				this._queue.unblock();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1354
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1355
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1356
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1357
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1358
		 * Get a specific relation.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1359
		 * @param {string} attr The relation key to look for.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1360
		 * @return {Backbone.Relation} An instance of 'Backbone.Relation', if a relation was found for 'attr', or null.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1361
		 */
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1362
		getRelation: function( attr ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1363
			return this._relations[ attr ];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1364
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1365
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1366
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1367
		 * Get all of the created relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1368
		 * @return {Backbone.Relation[]}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1369
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1370
		getRelations: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1371
			return _.values( this._relations );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1372
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1373
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1374
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1375
		/**
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1376
		 * Get a list of ids that will be fetched on a call to `getAsync`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1377
		 * @param {string|Backbone.Relation} attr The relation key to fetch models for.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1378
		 * @param [refresh=false] Add ids for models that are already in the relation, refreshing them?
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1379
		 * @return {Array} An array of ids that need to be fetched.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1380
		 */
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1381
		getIdsToFetch: function( attr, refresh ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1382
			var rel = attr instanceof Backbone.Relation ? attr : this.getRelation( attr ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1383
				ids = rel ? ( rel.keyIds && rel.keyIds.slice( 0 ) ) || ( ( rel.keyId || rel.keyId === 0 ) ? [ rel.keyId ] : [] ) : [];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1384
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1385
			// On `refresh`, add the ids for current models in the relation to `idsToFetch`
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1386
			if ( refresh ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1387
				var models = rel.related && ( rel.related.models || [ rel.related ] );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1388
				_.each( models, function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1389
					if ( model.id || model.id === 0 ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1390
						ids.push( model.id );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1391
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1392
				});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1393
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1394
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1395
			return ids;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1396
		},
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1397
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1398
		/**
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1399
		 * Get related objects. Returns a single promise, which can either resolve immediately (if the related model[s])
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1400
		 * are already present locally, or after fetching the contents of the requested attribute.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1401
		 * @param {string} attr The relation key to fetch models for.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1402
		 * @param {Object} [options] Options for 'Backbone.Model.fetch' and 'Backbone.sync'.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1403
		 * @param {Boolean} [options.refresh=false] Fetch existing models from the server as well (in order to update them).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1404
		 * @return {jQuery.Deferred} A jQuery promise object. When resolved, its `done` callback will be called with
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1405
		 *  contents of `attr`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1406
		 */
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1407
		getAsync: function( attr, options ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1408
			// Set default `options` for fetch
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1409
			options = _.extend( { add: true, remove: false, refresh: false }, options );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1410
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1411
			var dit = this,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1412
				requests = [],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1413
				rel = this.getRelation( attr ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1414
				idsToFetch = rel && this.getIdsToFetch( rel, options.refresh ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1415
				coll = rel.related instanceof Backbone.Collection ? rel.related : rel.relatedCollection;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1416
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1417
			if ( idsToFetch && idsToFetch.length ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1418
				var models = [],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1419
					createdModels = [],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1420
					setUrl,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1421
					createModels = function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1422
						// Find (or create) a model for each one that is to be fetched
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1423
						models = _.map( idsToFetch, function( id ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1424
							var model = rel.relatedModel.findModel( id );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1425
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1426
							if ( !model ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1427
								var attrs = {};
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1428
								attrs[ rel.relatedModel.prototype.idAttribute ] = id;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1429
								model = rel.relatedModel.findOrCreate( attrs, options );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1430
								createdModels.push( model );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1431
							}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1432
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1433
							return model;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1434
						}, this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1435
					};
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1436
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1437
				// Try if the 'collection' can provide a url to fetch a set of models in one request.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1438
				// This assumes that when 'Backbone.Collection.url' is a function, it can handle building of set urls.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1439
				// To make sure it can, test if the url we got by supplying a list of models to fetch is different from
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1440
				// the one supplied for the default fetch action (without args to 'url').
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1441
				if ( coll instanceof Backbone.Collection && _.isFunction( coll.url ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1442
					var defaultUrl = coll.url();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1443
					setUrl = coll.url( idsToFetch );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1444
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1445
					if ( setUrl === defaultUrl ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1446
						createModels();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1447
						setUrl = coll.url( models );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1448
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1449
						if ( setUrl === defaultUrl ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1450
							setUrl = null;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1451
						}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1452
					}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1453
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1454
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1455
				if ( setUrl ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1456
					// Do a single request to fetch all models
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1457
					var opts = _.defaults(
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1458
						{
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1459
							error: function() {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1460
								_.each( createdModels, function( model ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1461
									model.trigger( 'destroy', model, model.collection, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1462
								});
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1463
								
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1464
								options.error && options.error.apply( models, arguments );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1465
							},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1466
							url: setUrl
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1467
						},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1468
						options
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1469
					);
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1470
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1471
					requests = [ coll.fetch( opts ) ];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1472
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1473
				else {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1474
					// Make a request per model to fetch
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1475
					if  ( !models.length ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1476
						createModels();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1477
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1478
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1479
					requests = _.map( models, function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1480
						var opts = _.defaults(
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1481
							{
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1482
								error: function() {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1483
									if ( _.contains( createdModels, model ) ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1484
										model.trigger( 'destroy', model, model.collection, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1485
									}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1486
									options.error && options.error.apply( models, arguments );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1487
								}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1488
							},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1489
							options
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1490
						);
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1491
						return model.fetch( opts );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1492
					}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1493
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1494
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1495
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1496
			return this.deferArray(requests).then(
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1497
				function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1498
					return Backbone.Model.prototype.get.call( dit, attr );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1499
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1500
			);
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1501
		},
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1502
		
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1503
		deferArray: function(deferArray) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1504
			return Backbone.$.when.apply(null, deferArray);
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1505
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1506
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1507
		set: function( key, value, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1508
			Backbone.Relational.eventQueue.block();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1509
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1510
			// Duplicate backbone's behavior to allow separate key/value parameters, instead of a single 'attributes' object
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1511
			var attributes,
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1512
				result;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1513
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1514
			if ( _.isObject( key ) || key == null ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1515
				attributes = key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1516
				options = value;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1517
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1518
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1519
				attributes = {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1520
				attributes[ key ] = value;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1521
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1522
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1523
			try {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1524
				var id = this.id,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1525
					newId = attributes && this.idAttribute in attributes && attributes[ this.idAttribute ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1526
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1527
				// Check if we're not setting a duplicate id before actually calling `set`.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1528
				Backbone.Relational.store.checkId( this, newId );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1529
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1530
				result = Backbone.Model.prototype.set.apply( this, arguments );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1531
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1532
				// Ideal place to set up relations, if this is the first time we're here for this model
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1533
				if ( !this._isInitialized && !this.isLocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1534
					this.constructor.initializeModelHierarchy();
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1535
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1536
					// Only register models that have an id. A model will be registered when/if it gets an id later on.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1537
					if ( newId || newId === 0 ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1538
						Backbone.Relational.store.register( this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1539
					}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1540
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1541
					this.initializeRelations( options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1542
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1543
				// The store should know about an `id` update asap
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1544
				else if ( newId && newId !== id ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1545
					Backbone.Relational.store.update( this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1546
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1547
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1548
				if ( attributes ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1549
					this.updateRelations( attributes, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1550
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1551
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1552
			finally {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1553
				// Try to run the global queue holding external events
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1554
				Backbone.Relational.eventQueue.unblock();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1555
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1556
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1557
			return result;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1558
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1559
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1560
		clone: function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1561
			var attributes = _.clone( this.attributes );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1562
			if ( !_.isUndefined( attributes[ this.idAttribute ] ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1563
				attributes[ this.idAttribute ] = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1564
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1565
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1566
			_.each( this.getRelations(), function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1567
				delete attributes[ rel.key ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1568
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1569
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1570
			return new this.constructor( attributes );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1571
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1572
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1573
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1574
		 * Convert relations to JSON, omits them when required
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1575
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1576
		toJSON: function( options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1577
			// If this Model has already been fully serialized in this branch once, return to avoid loops
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1578
			if ( this.isLocked() ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1579
				return this.id;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1580
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1581
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1582
			this.acquire();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1583
			var json = Backbone.Model.prototype.toJSON.call( this, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1584
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1585
			if ( this.constructor._superModel && !( this.constructor._subModelTypeAttribute in json ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1586
				json[ this.constructor._subModelTypeAttribute ] = this.constructor._subModelTypeValue;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1587
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1588
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1589
			_.each( this._relations, function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1590
				var related = json[ rel.key ],
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1591
					includeInJSON = rel.options.includeInJSON,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1592
					value = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1593
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1594
				if ( includeInJSON === true ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1595
					if ( related && _.isFunction( related.toJSON ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1596
						value = related.toJSON( options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1597
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1598
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1599
				else if ( _.isString( includeInJSON ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1600
					if ( related instanceof Backbone.Collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1601
						value = related.pluck( includeInJSON );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1602
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1603
					else if ( related instanceof Backbone.Model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1604
						value = related.get( includeInJSON );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1605
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1606
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1607
					// Add ids for 'unfound' models if includeInJSON is equal to (only) the relatedModel's `idAttribute`
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1608
					if ( includeInJSON === rel.relatedModel.prototype.idAttribute ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1609
						if ( rel instanceof Backbone.HasMany ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1610
							value = value.concat( rel.keyIds );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1611
						}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1612
						else if ( rel instanceof Backbone.HasOne ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1613
							value = value || rel.keyId;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1614
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1615
							if ( !value && !_.isObject( rel.keyContents ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1616
								value = rel.keyContents || null;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1617
							}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1618
						}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1619
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1620
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1621
				else if ( _.isArray( includeInJSON ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1622
					if ( related instanceof Backbone.Collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1623
						value = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1624
						related.each( function( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1625
							var curJson = {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1626
							_.each( includeInJSON, function( key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1627
								curJson[ key ] = model.get( key );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1628
							});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1629
							value.push( curJson );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1630
						});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1631
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1632
					else if ( related instanceof Backbone.Model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1633
						value = {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1634
						_.each( includeInJSON, function( key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1635
							value[ key ] = related.get( key );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1636
						});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1637
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1638
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1639
				else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1640
					delete json[ rel.key ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1641
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1642
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1643
				// In case of `wait: true`, Backbone will simply push whatever's passed into `save` into attributes.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1644
				// We'll want to get this information into the JSON, even if it doesn't conform to our normal
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1645
				// expectations of what's contained in it (no model/collection for a relation, etc).
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1646
				if ( value === null && options && options.wait ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1647
					value = related;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1648
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1649
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1650
				if ( includeInJSON ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1651
					json[ rel.keyDestination ] = value;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1652
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1653
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1654
				if ( rel.keyDestination !== rel.key ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1655
					delete json[ rel.key ];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1656
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1657
			});
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1658
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1659
			this.release();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1660
			return json;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1661
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1662
	},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1663
	{
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1664
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1665
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1666
		 * @param superModel
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1667
		 * @returns {Backbone.RelationalModel.constructor}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1668
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1669
		setup: function( superModel ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1670
			// We don't want to share a relations array with a parent, as this will cause problems with reverse
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1671
			// relations. Since `relations` may also be a property or function, only use slice if we have an array.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1672
			this.prototype.relations = ( this.prototype.relations || [] ).slice( 0 );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1673
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1674
			this._subModels = {};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1675
			this._superModel = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1676
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1677
			// If this model has 'subModelTypes' itself, remember them in the store
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1678
			if ( this.prototype.hasOwnProperty( 'subModelTypes' ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1679
				Backbone.Relational.store.addSubModels( this.prototype.subModelTypes, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1680
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1681
			// The 'subModelTypes' property should not be inherited, so reset it.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1682
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1683
				this.prototype.subModelTypes = null;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1684
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1685
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1686
			// Initialize all reverseRelations that belong to this new model.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1687
			_.each( this.prototype.relations || [], function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1688
				if ( !rel.model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1689
					rel.model = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1690
				}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1691
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1692
				if ( rel.reverseRelation && rel.model === this ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1693
					var preInitialize = true;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1694
					if ( _.isString( rel.relatedModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1695
						/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1696
						 * The related model might not be defined for two reasons
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1697
						 *  1. it is related to itself
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1698
						 *  2. it never gets defined, e.g. a typo
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1699
						 *  3. the model hasn't been defined yet, but will be later
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1700
						 * In neither of these cases do we need to pre-initialize reverse relations.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1701
						 * However, for 3. (which is, to us, indistinguishable from 2.), we do need to attempt
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1702
						 * setting up this relation again later, in case the related model is defined later.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1703
						 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1704
						var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1705
						preInitialize = relatedModel && ( relatedModel.prototype instanceof Backbone.RelationalModel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1706
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1707
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1708
					if ( preInitialize ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1709
						Backbone.Relational.store.initializeRelation( null, rel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1710
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1711
					else if ( _.isString( rel.relatedModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1712
						Backbone.Relational.store.addOrphanRelation( rel );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1713
					}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1714
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1715
			}, this );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1716
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1717
			return this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1718
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1719
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1720
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1721
		 * Create a 'Backbone.Model' instance based on 'attributes'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1722
		 * @param {Object} attributes
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1723
		 * @param {Object} [options]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1724
		 * @return {Backbone.Model}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1725
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1726
		build: function( attributes, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1727
			// 'build' is a possible entrypoint; it's possible no model hierarchy has been determined yet.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1728
			this.initializeModelHierarchy();
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1729
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1730
			// Determine what type of (sub)model should be built if applicable.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1731
			var model = this._findSubModelType( this, attributes ) || this;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1732
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1733
			return new model( attributes, options );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1734
		},
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1735
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1736
		/**
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1737
		 * Determines what type of (sub)model should be built if applicable.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1738
		 * Looks up the proper subModelType in 'this._subModels', recursing into
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1739
		 * types until a match is found.  Returns the applicable 'Backbone.Model'
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1740
		 * or null if no match is found.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1741
		 * @param {Backbone.Model} type
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1742
		 * @param {Object} attributes
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1743
		 * @return {Backbone.Model}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1744
		 */
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1745
		_findSubModelType: function( type, attributes ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1746
			if ( type._subModels && type.prototype.subModelTypeAttribute in attributes ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1747
				var subModelTypeAttribute = attributes[ type.prototype.subModelTypeAttribute ];
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1748
				var subModelType = type._subModels[ subModelTypeAttribute ];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1749
				if ( subModelType ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1750
					return subModelType;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1751
				}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1752
				else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1753
					// Recurse into subModelTypes to find a match
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1754
					for ( subModelTypeAttribute in type._subModels ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1755
						subModelType = this._findSubModelType( type._subModels[ subModelTypeAttribute ], attributes );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1756
						if ( subModelType ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1757
							return subModelType;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1758
						}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1759
					}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1760
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1761
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1762
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1763
			return null;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1764
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1765
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1766
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1767
		 *
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1768
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1769
		initializeModelHierarchy: function() {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1770
			// Inherit any relations that have been defined in the parent model.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1771
			this.inheritRelations();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1772
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1773
			// If we came here through 'build' for a model that has 'subModelTypes' then try to initialize the ones that
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1774
			// haven't been resolved yet.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1775
			if ( this.prototype.subModelTypes ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1776
				var resolvedSubModels = _.keys( this._subModels );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1777
				var unresolvedSubModels = _.omit( this.prototype.subModelTypes, resolvedSubModels );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1778
				_.each( unresolvedSubModels, function( subModelTypeName ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1779
					var subModelType = Backbone.Relational.store.getObjectByName( subModelTypeName );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1780
					subModelType && subModelType.initializeModelHierarchy();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1781
				});
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1782
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1783
		},
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1784
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1785
		inheritRelations: function() {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1786
			// Bail out if we've been here before.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1787
			if ( !_.isUndefined( this._superModel ) && !_.isNull( this._superModel ) ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1788
				return;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1789
			}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1790
			// Try to initialize the _superModel.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1791
			Backbone.Relational.store.setupSuperModel( this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1792
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1793
			// If a superModel has been found, copy relations from the _superModel if they haven't been inherited automatically
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1794
			// (due to a redefinition of 'relations').
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1795
			if ( this._superModel ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1796
				// The _superModel needs a chance to initialize its own inherited relations before we attempt to inherit relations
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1797
				// from the _superModel. You don't want to call 'initializeModelHierarchy' because that could cause sub-models of
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1798
				// this class to inherit their relations before this class has had chance to inherit it's relations.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1799
				this._superModel.inheritRelations();
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1800
				if ( this._superModel.prototype.relations ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1801
					// Find relations that exist on the '_superModel', but not yet on this model.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1802
					var inheritedRelations = _.filter( this._superModel.prototype.relations || [], function( superRel ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1803
						return !_.any( this.prototype.relations || [], function( rel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1804
							return superRel.relatedModel === rel.relatedModel && superRel.key === rel.key;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1805
						}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1806
					}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1807
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1808
					this.prototype.relations = inheritedRelations.concat( this.prototype.relations );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1809
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1810
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1811
			// Otherwise, make sure we don't get here again for this type by making '_superModel' false so we fail the
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1812
			// isUndefined/isNull check next time.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1813
			else {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1814
				this._superModel = false;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1815
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1816
		},
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1817
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1818
		/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1819
		 * Find an instance of `this` type in 'Backbone.Relational.store'.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1820
		 * A new model is created if no matching model is found, `attributes` is an object, and `options.create` is true.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1821
		 * - If `attributes` is a string or a number, `findOrCreate` will query the `store` and return a model if found.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1822
		 * - If `attributes` is an object and is found in the store, the model will be updated with `attributes` unless `options.merge` is `false`.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1823
		 * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1824
		 * @param {Object} [options]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1825
		 * @param {Boolean} [options.create=true]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1826
		 * @param {Boolean} [options.merge=true]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1827
		 * @param {Boolean} [options.parse=false]
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1828
		 * @return {Backbone.RelationalModel}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1829
		 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1830
		findOrCreate: function( attributes, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1831
			options || ( options = {} );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1832
			var parsedAttributes = ( _.isObject( attributes ) && options.parse && this.prototype.parse ) ?
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1833
				this.prototype.parse( _.clone( attributes ), options ) : attributes;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1834
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1835
			// If specified, use a custom `find` function to match up existing models to the given attributes.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1836
			// Otherwise, try to find an instance of 'this' model type in the store
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1837
			var model = this.findModel( parsedAttributes );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1838
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1839
			// If we found an instance, update it with the data in 'item' (unless 'options.merge' is false).
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1840
			// If not, create an instance (unless 'options.create' is false).
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1841
			if ( _.isObject( attributes ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1842
				if ( model && options.merge !== false ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1843
					// Make sure `options.collection` and `options.url` doesn't cascade to nested models
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1844
					delete options.collection;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1845
					delete options.url;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1846
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1847
					model.set( parsedAttributes, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1848
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1849
				else if ( !model && options.create !== false ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1850
					model = this.build( parsedAttributes, _.defaults( { parse: false }, options ) );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1851
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1852
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1853
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1854
			return model;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1855
		},
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1856
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1857
		/**
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1858
		 * Find an instance of `this` type in 'Backbone.Relational.store'.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1859
		 * - If `attributes` is a string or a number, `find` will query the `store` and return a model if found.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1860
		 * - If `attributes` is an object and is found in the store, the model will be updated with `attributes` unless `options.merge` is `false`.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1861
		 * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1862
		 * @param {Object} [options]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1863
		 * @param {Boolean} [options.merge=true]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1864
		 * @param {Boolean} [options.parse=false]
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1865
		 * @return {Backbone.RelationalModel}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1866
		 */
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1867
		find: function( attributes, options ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1868
			options || ( options = {} );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1869
			options.create = false;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1870
			return this.findOrCreate( attributes, options );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1871
		},
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1872
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1873
		/**
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1874
		 * A hook to override the matching when updating (or creating) a model.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1875
		 * The default implementation is to look up the model by id in the store.
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1876
		 * @param {Object} attributes
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1877
		 * @returns {Backbone.RelationalModel}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1878
		 */
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1879
		findModel: function( attributes ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1880
			return Backbone.Relational.store.find( this, attributes );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1881
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1882
	});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1883
	_.extend( Backbone.RelationalModel.prototype, Backbone.Semaphore );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1884
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1885
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1886
	 * Override Backbone.Collection._prepareModel, so objects will be built using the correct type
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1887
	 * if the collection.model has subModels.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1888
	 * Attempts to find a model for `attrs` in Backbone.store through `findOrCreate`
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1889
	 * (which sets the new properties on it if found), or instantiates a new model.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1890
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1891
	Backbone.Collection.prototype.__prepareModel = Backbone.Collection.prototype._prepareModel;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1892
	Backbone.Collection.prototype._prepareModel = function( attrs, options ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1893
		var model;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1894
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1895
		if ( attrs instanceof Backbone.Model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1896
			if ( !attrs.collection ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1897
				attrs.collection = this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1898
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1899
			model = attrs;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1900
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1901
		else {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1902
			options = options ? _.clone( options ) : {};
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1903
			options.collection = this;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1904
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1905
			if ( typeof this.model.findOrCreate !== 'undefined' ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1906
				model = this.model.findOrCreate( attrs, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1907
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1908
			else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1909
				model = new this.model( attrs, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1910
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1911
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1912
			if ( model && model.validationError ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1913
				this.trigger( 'invalid', this, attrs, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1914
				model = false;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1915
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1916
		}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1917
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1918
		return model;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1919
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1920
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1921
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1922
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1923
	 * Override Backbone.Collection.set, so we'll create objects from attributes where required,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1924
	 * and update the existing models. Also, trigger 'relational:add'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1925
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1926
	var set = Backbone.Collection.prototype.__set = Backbone.Collection.prototype.set;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1927
	Backbone.Collection.prototype.set = function( models, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1928
		// Short-circuit if this Collection doesn't hold RelationalModels
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1929
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1930
			return set.call( this, models, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1931
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1932
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1933
		if ( options && options.parse ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1934
			models = this.parse( models, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1935
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1936
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1937
		var singular = !_.isArray( models ),
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1938
			newModels = [],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1939
			toAdd = [],
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1940
			model = null;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1941
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1942
		models = singular ? ( models ? [ models ] : [] ) : _.clone( models );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1943
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1944
		//console.debug( 'calling add on coll=%o; model=%o, options=%o', this, models, options );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1945
		for ( var i = 0; i < models.length; i++ ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1946
			model = models[i];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1947
			if ( !( model instanceof Backbone.Model ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1948
				model = Backbone.Collection.prototype._prepareModel.call( this, model, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1949
			}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1950
			if ( model ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1951
				toAdd.push( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1952
				if ( !( this.get( model ) || this.get( model.cid ) ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1953
					newModels.push( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1954
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1955
				// If we arrive in `add` while performing a `set` (after a create, so the model gains an `id`),
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1956
				// we may get here before `_onModelEvent` has had the chance to update `_byId`.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1957
				else if ( model.id !== null && model.id !== undefined ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1958
					this._byId[ model.id ] = model;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1959
				}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1960
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1961
		}
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1962
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1963
		// Add 'models' in a single batch, so the original add will only be called once (and thus 'sort', etc).
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1964
		// If `parse` was specified, the collection and contained models have been parsed now.
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1965
		toAdd = singular ? ( toAdd.length ? toAdd[ 0 ] : null ) : toAdd;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1966
		var result = set.call( this, toAdd, _.defaults( { merge: false, parse: false }, options ) );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1967
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1968
		for ( i = 0; i < newModels.length; i++ ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1969
			model = newModels[i];
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1970
			// Fire a `relational:add` event for any model in `newModels` that has actually been added to the collection.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1971
			if ( this.get( model ) || this.get( model.cid ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1972
				this.trigger( 'relational:add', model, this, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1973
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1974
		}
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1975
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1976
		return result;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1977
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1978
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1979
	/**
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1980
	 * Override 'Backbone.Collection._removeModels' to trigger 'relational:remove'.
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1981
	 */
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1982
	var _removeModels = Backbone.Collection.prototype.___removeModels = Backbone.Collection.prototype._removeModels;
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1983
	Backbone.Collection.prototype._removeModels = function( models, options ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1984
		// Short-circuit if this Collection doesn't hold RelationalModels
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1985
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1986
			return _removeModels.call( this, models, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1987
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1988
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1989
		var toRemove = [];
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1990
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1991
		//console.debug('calling remove on coll=%o; models=%o, options=%o', this, models, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1992
		_.each( models, function( model ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1993
			model = this.get( model ) || ( model && this.get( model.cid ) );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1994
			model && toRemove.push( model );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1995
		}, this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1996
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1997
		var result = _removeModels.call( this, toRemove, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  1998
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  1999
		_.each( toRemove, function( model ) {
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2000
			this.trigger( 'relational:remove', model, this, options );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2001
		}, this );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2002
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2003
		return result;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2004
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2005
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2006
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2007
	 * Override 'Backbone.Collection.reset' to trigger 'relational:reset'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2008
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2009
	var reset = Backbone.Collection.prototype.__reset = Backbone.Collection.prototype.reset;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2010
	Backbone.Collection.prototype.reset = function( models, options ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2011
		options = _.extend( { merge: true }, options );
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2012
		var result = reset.call( this, models, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2013
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2014
		if ( this.model.prototype instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2015
			this.trigger( 'relational:reset', this, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2016
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2017
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2018
		return result;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2019
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2020
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2021
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2022
	 * Override 'Backbone.Collection.sort' to trigger 'relational:reset'.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2023
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2024
	var sort = Backbone.Collection.prototype.__sort = Backbone.Collection.prototype.sort;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2025
	Backbone.Collection.prototype.sort = function( options ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2026
		var result = sort.call( this, options );
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2027
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2028
		if ( this.model.prototype instanceof Backbone.RelationalModel ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2029
			this.trigger( 'relational:reset', this, options );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2030
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2031
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2032
		return result;
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2033
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2034
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2035
	/**
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2036
	 * Override 'Backbone.Collection.trigger' so 'add', 'remove' and 'reset' events are queued until relations
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2037
	 * are ready.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2038
	 */
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2039
	var trigger = Backbone.Collection.prototype.__trigger = Backbone.Collection.prototype.trigger;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2040
	Backbone.Collection.prototype.trigger = function( eventName ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2041
		// Short-circuit if this Collection doesn't hold RelationalModels
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2042
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2043
			return trigger.apply( this, arguments );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2044
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2045
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2046
		if ( eventName === 'add' || eventName === 'remove' || eventName === 'reset' || eventName === 'sort' ) {
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2047
			var dit = this,
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2048
				args = arguments;
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2049
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2050
			if ( _.isObject( args[ 3 ] ) ) {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2051
				args = _.toArray( args );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2052
				// the fourth argument is the option object.
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2053
				// we need to clone it, as it could be modified while we wait on the eventQueue to be unblocked
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2054
				args[ 3 ] = _.clone( args[ 3 ] );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2055
			}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2056
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2057
			Backbone.Relational.eventQueue.add( function() {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2058
				trigger.apply( dit, args );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2059
			});
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2060
		}
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2061
		else {
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2062
			trigger.apply( this, arguments );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2063
		}
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2064
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2065
		return this;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2066
	};
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2067
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2068
	// Override .extend() to automatically call .setup()
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2069
	Backbone.RelationalModel.extend = function( protoProps, classProps ) {
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2070
		var child = Backbone.Model.extend.call( this, protoProps, classProps );
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2071
872
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2072
		child.setup( this );
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2073
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2074
		return child;
6b7c534792b7 Updated Metadataplayer for Renkan
Raphael Velt <raph.velt@gmail.com>
parents:
diff changeset
  2075
	};
1512
487ca37bb0c7 Upgrade backbone
ymh <ymh.work@gmail.com>
parents: 872
diff changeset
  2076
}));