UNPKG

backbone-rel

Version:

Relationships between Backbone models in the flavor of MongoDB's document references and embeddings

2,287 lines 119 kB
<!DOCTYPE html>

<html>
<head>
  <title>backbone-rel.js</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>backbone-rel.js</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              
            </div>
            
            <div class="content"><div class='highlight'><pre>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">root, factory</span>) </span>{
    <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> define === <span class="hljs-string">'function'</span> &amp;&amp; define.amd) {</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>AMD</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        define([<span class="hljs-string">'underscore'</span>, <span class="hljs-string">'backbone'</span>, <span class="hljs-string">'exports'</span>], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">_, Backbone, exports</span>) </span>{</pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Export global even in AMD case in case this script is loaded with
others that may still expect a global Backbone.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            root.Backbone = factory(root, exports, _, Backbone);
        });

    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> exports !== <span class="hljs-string">'undefined'</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>for Node.js or CommonJS</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        <span class="hljs-keyword">var</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'underscore'</span>),
            Backbone = <span class="hljs-built_in">require</span>(<span class="hljs-string">'backbone'</span>);

        factory(root, exports, _, Backbone);
    } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>as a browser global</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        root.Backbone = factory(root, {}, root._, root.Backbone);
    }

}(<span class="hljs-keyword">this</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">root, exports, _, BackboneBase</span>) </span>{

    <span class="hljs-keyword">var</span> Backbone = _.extend({}, BackboneBase);


    <span class="hljs-keyword">var</span> modelOptions = [<span class="hljs-string">'url'</span>, <span class="hljs-string">'urlRoot'</span>, <span class="hljs-string">'collection'</span>];


    Backbone.Model = BackboneBase.Model.extend({

        references: {},

        embeddings: {},</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>Property to control whether a related object shall be inlined in this model’s JSON representation.
Useful when the related object shall be saved to the server together with its parent/referencing object.
If a relationship key is added as a string to this array, the result of #toJSON() will have
a property of that key, under which the related object’s JSON representation is nested.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        inlineJSON: [],</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Property to control whether referenced objects shall be fetched automcatically when set.</p>
<ul>
<li><code>true</code> (default) will cause all referenced objects to be fetched automatically</li>
<li><code>false</code> will cause that referenced objects are never fetched automatically</li>
<li>Setting an array of reference key strings, allows to explicitly specify which references
shall be auto-fetched.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        autoFetchRelated: <span class="hljs-literal">true</span>,

        constructor: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">attributes, options</span>) </span>{
            <span class="hljs-keyword">var</span> attrs = attributes || {};

            <span class="hljs-keyword">this</span>.cid = _.uniqueId(<span class="hljs-string">'c'</span>);
            options || (options = {});
            <span class="hljs-keyword">this</span>.attributes = {};
            _.extend(<span class="hljs-keyword">this</span>, _.pick(options, modelOptions));

            <span class="hljs-keyword">this</span>.relatedObjects = {};
            <span class="hljs-keyword">this</span>._relatedObjectsToFetch = [];

            <span class="hljs-keyword">this</span>._updateIdRefFor = {};</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>handle default values for relations</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> defaults,
                references = <span class="hljs-keyword">this</span>.references,
                referenceAttributeName = <span class="hljs-keyword">this</span>.referenceAttributeName.bind(<span class="hljs-keyword">this</span>);

            <span class="hljs-keyword">if</span>(options.parse) attrs = <span class="hljs-keyword">this</span>.parse(attrs, options) || {};

            <span class="hljs-keyword">if</span>(defaults = _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'defaults'</span>)) {
                defaults = _.extend({}, defaults); <span class="hljs-comment">// clone</span>
                _.each(_.keys(references), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">refKey</span>) </span>{</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>do not set default value for referenced object attribute
if attrs contain a corresponding ID reference</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(referenceAttributeName(refKey) <span class="hljs-keyword">in</span> attrs &amp;&amp; refKey <span class="hljs-keyword">in</span> defaults) {
                        <span class="hljs-keyword">delete</span> defaults[refKey];
                    }
                });
                attrs = _.defaults({}, attrs, defaults);
            }
            <span class="hljs-keyword">this</span>.set(attrs, options);
            <span class="hljs-keyword">this</span>.changed = {};

            <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.isNew()) {
                <span class="hljs-keyword">this</span>._autoFetchEmbeddings(<span class="hljs-literal">true</span>);
            }

            <span class="hljs-keyword">this</span>.initialize.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Returns the URL for this model</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        url: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">var</span> base =
                _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'urlRoot'</span>) ||
                _.result(<span class="hljs-keyword">this</span>.collection, <span class="hljs-string">'url'</span>);
            <span class="hljs-keyword">var</span> suffix = _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'urlSuffix'</span>);
            <span class="hljs-keyword">if</span>(base) {
                <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.isNew()) <span class="hljs-keyword">return</span> base;
                <span class="hljs-keyword">return</span> base.replace(<span class="hljs-regexp">/([^\/])$/</span>, <span class="hljs-string">'$1/'</span>) + <span class="hljs-built_in">encodeURIComponent</span>(<span class="hljs-keyword">this</span>.id);
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent) {
                <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent.isNew() &amp;&amp; !<span class="hljs-keyword">this</span>.parent.parent) {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Could not get the parent model's URL as it has not been saved yet."</span>);
                }
                base = _.result(<span class="hljs-keyword">this</span>.parent, <span class="hljs-string">'url'</span>);
                <span class="hljs-keyword">if</span>(base &amp;&amp; suffix) {
                    <span class="hljs-keyword">return</span> base.replace(<span class="hljs-regexp">/([^\/])$/</span>, <span class="hljs-string">'$1/'</span>) + suffix.replace(<span class="hljs-regexp">/(\/?)(.*)/</span>, <span class="hljs-string">'$2'</span>);
                }
            }

            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Could not build url for the model with ID "'</span> + <span class="hljs-keyword">this</span>.id + <span class="hljs-string">'" (URL suffix: "'</span> + suffix + <span class="hljs-string">'")'</span>);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>For embedded models, returns the suffix to append to the parent model’s URL
for building the URL for the embedded model instance.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        urlSuffix: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>,
                parent = <span class="hljs-keyword">this</span>.parent;
            <span class="hljs-keyword">return</span> parent &amp;&amp; _.find(_.keys(parent.embeddings), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">return</span> parent.get(key) === self;
            });
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>For models with references, returns the attribute name under which the IDs of referenced
objects for the given reference key are stored.
Per default, the attribute name is built by using the reference key + the ID attribute of the
referenced model. E.g: “userId” for reference key “user” to a model with ID attribute “id”,
“userIds” for a to-many reference.
Override this method to customize the reference attribute naming pattern.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        referenceAttributeName: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">referenceKey</span>) </span>{
            <span class="hljs-keyword">var</span> referencedModel = resolveRelClass(<span class="hljs-keyword">this</span>.references[referenceKey]);
            <span class="hljs-keyword">return</span> refKeyToIdRefKey(referencedModel, referenceKey);
        },

        get: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) </span>{
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.embeddings[attr] || <span class="hljs-keyword">this</span>.references[attr]) {</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-13">&#182;</a>
              </div>
              <p>return related object if the key corresponds to a reference or embedding</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.relatedObjects[attr];
            } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-14">&#182;</a>
              </div>
              <p>otherwise return the regular attribute</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">return</span> BackboneBase.Model.prototype.get.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
            }
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-15">&#182;</a>
              </div>
              <p>Set a hash of model attributes and relations on the object, firing <code>&quot;change&quot;</code>. This is
the core primitive operation of a model, updating the data and notifying
anyone who needs to know about the change in state. The heart of the beast.
ATTENTION: This is a full override of Backbone’s default implementation meaning that
it will not call the base class method. If you are using third Backbone extensions that
override #set, make sure that these extend backbone-rel’ Model class.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        set: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, val, options</span>) </span>{
            <span class="hljs-keyword">var</span> attr, attrs, unset, changes, silent, changing, prev, current, referenceKey;
            <span class="hljs-keyword">if</span>(key === <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-16">&#182;</a>
              </div>
              <p>Handle both <code>&quot;key&quot;, value</code> and <code>{key: value}</code> -style arguments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">'object'</span>) {
                attrs = key;
                options = val;
            } <span class="hljs-keyword">else</span> {
                (attrs = {})[key] = val;
            }

            options || (options = {});</pre></div></div>
            
        </li>
        
        
        <li id="section-17">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-17">&#182;</a>
              </div>
              <p>Pass the setOriginId down to the nested set calls via options.
Also support <code>nestedSetOptions</code> to define options that shall only be applied to nested</p>
<h1 id="set-calls-for-related-object-">set calls for related object.</h1>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> nestedOptions = _.extend(
                { setOriginId: _.uniqueId() }, options, 
                { clear: <span class="hljs-literal">undefined</span> },  <span class="hljs-comment">// `clear` option should not propagate to nested set calls</span>
                { nestedSetOptions: <span class="hljs-literal">undefined</span> },
                options.nestedSetOptions
            );
            <span class="hljs-keyword">if</span>(nestedOptions.collection) {</pre></div></div>
            
        </li>
        
        
        <li id="section-18">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-18">&#182;</a>
              </div>
              <p><code>collection</code> option should not propagate to nested set calls</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">delete</span> nestedOptions.collection;
            }

            <span class="hljs-keyword">this</span>._deepChangePropagatedFor = [];</pre></div></div>
            
        </li>
        
        
        <li id="section-19">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-19">&#182;</a>
              </div>
              <p>Run validation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>._validate(attrs, options)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-20">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-20">&#182;</a>
              </div>
              <p>Extract attributes and options.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            unset           = options.unset;
            silent          = options.silent;
            changes         = [];
            changing        = <span class="hljs-keyword">this</span>._changing;
            <span class="hljs-keyword">this</span>._changing  = <span class="hljs-literal">true</span>;

            <span class="hljs-keyword">if</span>(!changing) {
                <span class="hljs-keyword">this</span>._previousAttributes = _.clone(<span class="hljs-keyword">this</span>.attributes);
                <span class="hljs-keyword">this</span>._previousRelatedObjects = _.clone(<span class="hljs-keyword">this</span>.relatedObjects);
                <span class="hljs-keyword">this</span>.changed = {};
            }
            current = <span class="hljs-keyword">this</span>.attributes, prev = <span class="hljs-keyword">this</span>._previousAttributes;</pre></div></div>
            
        </li>
        
        
        <li id="section-21">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-21">&#182;</a>
              </div>
              <p>Check for changes of <code>id</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.idAttribute <span class="hljs-keyword">in</span> attrs) <span class="hljs-keyword">this</span>.id = attrs[<span class="hljs-keyword">this</span>.idAttribute];</pre></div></div>
            
        </li>
        
        
        <li id="section-22">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-22">&#182;</a>
              </div>
              <p>Precalculate the idRefKeys for all references to improve performance of the lookups</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> refKeys = _.keys(<span class="hljs-keyword">this</span>.references);
            <span class="hljs-keyword">var</span> refAndIdRefKeys = {};
            <span class="hljs-keyword">var</span> i;

            <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;refKeys.length; i++) {
                refAndIdRefKeys[refKeys[i]] = refKeys[i];
                refAndIdRefKeys[<span class="hljs-keyword">this</span>.referenceAttributeName(refKeys[i])] = refKeys[i];
            }

            <span class="hljs-keyword">var</span> findReferenceKey = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">return</span> refAndIdRefKeys[key];
            };</pre></div></div>
            
        </li>
        
        
        <li id="section-23">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-23">&#182;</a>
              </div>
              <p>If <code>clear</code> is set, calculate the keys to be unset and add those keys to attrs</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> keysToUnset = [];
            <span class="hljs-keyword">if</span>(options.clear) {
                <span class="hljs-keyword">var</span> defaults = _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'defaults'</span>) || {};

                keysToUnset = _.difference(
                    _.union(_.keys(<span class="hljs-keyword">this</span>.attributes), _.keys(<span class="hljs-keyword">this</span>.relatedObjects)),
                    _.keys(attrs),
                    _.map(_.keys(attrs), findReferenceKey)
                );</pre></div></div>
            
        </li>
        
        
        <li id="section-24">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-24">&#182;</a>
              </div>
              <p>clone because the keysToUnset array is modified from within the loop</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">var</span> keysToUnsetCopy = _.clone(keysToUnset);
                <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>, l=keysToUnsetCopy.length; i&lt;l; ++i) {
                    <span class="hljs-keyword">var</span> keyToUnset = keysToUnsetCopy[i];
                    <span class="hljs-keyword">if</span>(defaults.hasOwnProperty(keyToUnset)) {</pre></div></div>
            
        </li>
        
        
        <li id="section-25">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-25">&#182;</a>
              </div>
              <p>reset to default value instead of deleting</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        <span class="hljs-keyword">var</span> defVal = defaults[keyToUnset];</pre></div></div>
            
        </li>
        
        
        <li id="section-26">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-26">&#182;</a>
              </div>
              <p>ensure that the default for a reference/embedding is an actual Backbone 
model/collection and not just a plain JSON hash or array (which would be 
applied to the current referenced objects instead of replacing them)</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        <span class="hljs-keyword">if</span>(defVal &amp;&amp; !defVal._representsToMany &amp;&amp; !defVal._representsToOne) {
                           <span class="hljs-keyword">var</span> relationship = <span class="hljs-keyword">this</span>.embeddings[keyToUnset] || <span class="hljs-keyword">this</span>.references[keyToUnset];
                           <span class="hljs-keyword">var</span> RelClass = relationship &amp;&amp; resolveRelClass(relationship);
                           <span class="hljs-keyword">if</span>(RelClass) defVal = <span class="hljs-keyword">new</span> RelClass(defVal, nestedOptions);
                        }

                        attrs[keyToUnset] = defVal;
                        keysToUnset = _.without(keysToUnset, keyToUnset);
                    } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-27">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-27">&#182;</a>
              </div>
              <p>add to attrs just to make sure the key will be traversed in the for loop</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        attrs[keyToUnset] = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
                    }
                }
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-28">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-28">&#182;</a>
              </div>
              <p>For each <code>set</code> attribute, update or delete the current value.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">for</span> (attr <span class="hljs-keyword">in</span> attrs) {

                val = attrs[attr];

                <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.embeddings[attr]) {

                    <span class="hljs-keyword">var</span> opts = _.extend({}, nestedOptions, { clear: options.clear },  { unset: unset || _.contains(keysToUnset, attr) });
                    <span class="hljs-keyword">this</span>._setEmbedding(attr, val, opts, changes);

                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(referenceKey = findReferenceKey(attr)) {</pre></div></div>
            
        </li>
        
        
        <li id="section-29">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-29">&#182;</a>
              </div>
              <p>side-loaded JSON structures take precedence over ID references</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(attr !== referenceKey &amp;&amp; attrs[referenceKey]) {</pre></div></div>
            
        </li>
        
        
        <li id="section-30">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-30">&#182;</a>
              </div>
              <p>is ID ref, but also side-loaded data is present in attrs</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        <span class="hljs-keyword">continue</span>; <span class="hljs-comment">// ignore attr</span>
                    }
                    <span class="hljs-keyword">var</span> opts = _.extend({}, nestedOptions, { unset: unset || _.contains(keysToUnset, referenceKey) });
                    <span class="hljs-keyword">this</span>._setReference(referenceKey, val, opts, changes);

                } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-31">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-31">&#182;</a>
              </div>
              <p>default Backbone behavior for plain attribute set</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(!_.isEqual(current[attr], val)) changes.push(attr);
                    <span class="hljs-keyword">if</span>(!_.isEqual(prev[attr], val)) {
                        <span class="hljs-keyword">this</span>.changed[attr] = val;
                    } <span class="hljs-keyword">else</span> {
                        <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.changed[attr];
                    }
                    unset || _.contains(keysToUnset, attr) ? <span class="hljs-keyword">delete</span> current[attr] : current[attr] = val;

                }
            }

            <span class="hljs-keyword">var</span> currentAll = _.extend({}, current, <span class="hljs-keyword">this</span>.relatedObjects);</pre></div></div>
            
        </li>
        
        
        <li id="section-32">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-32">&#182;</a>
              </div>
              <p>Trigger all relevant attribute changes.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(!silent) {
                <span class="hljs-keyword">if</span>(changes.length) <span class="hljs-keyword">this</span>._pending = <span class="hljs-literal">true</span>;
                <span class="hljs-keyword">var</span> l;
                <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, l = changes.length; i &lt; l; i++) {
                    <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'change:'</span> + changes[i], <span class="hljs-keyword">this</span>, currentAll[changes[i]], options);
                }
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-33">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-33">&#182;</a>
              </div>
              <p>You might be wondering why there’s a <code>while</code> loop here. Changes can
be recursively nested within <code>&quot;change&quot;</code> events.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(changing) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
            <span class="hljs-keyword">if</span>(!silent) {
                <span class="hljs-keyword">while</span> (<span class="hljs-keyword">this</span>._pending) {
                    <span class="hljs-keyword">this</span>._pending = <span class="hljs-literal">false</span>;
                    <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'change'</span>, <span class="hljs-keyword">this</span>, options);
                }
            }
            <span class="hljs-keyword">this</span>._pending = <span class="hljs-literal">false</span>;
            <span class="hljs-keyword">this</span>._changing = <span class="hljs-literal">false</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-34">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-34">&#182;</a>
              </div>
              <p>Trigger original ‘deepchange’ event, which will be propagated through the related object graph</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(!silent &amp;&amp; changes.length &amp;&amp; !_.contains(<span class="hljs-keyword">this</span>._deepChangePropagatedFor, nestedOptions.setOriginId)) {
                <span class="hljs-keyword">this</span>._deepChangePropagatedFor.push(nestedOptions.setOriginId);
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange'</span>, <span class="hljs-keyword">this</span>, _.extend({ setOriginId: nestedOptions.setOriginId }, options));
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange_propagated'</span>, <span class="hljs-keyword">this</span>, _.extend({ setOriginId: nestedOptions.setOriginId }, options));
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-35">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-35">&#182;</a>
              </div>
              <p>finally, fetch all related objects that need a fetch</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">this</span>._fetchRelatedObjects();

            <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-36">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-36">&#182;</a>
              </div>
              <p>Fetches the related object for each key in the provided keys array
If no keys array is provided, it fetches the related objects for all
relations that have not been synced before</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        fetchRelated: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">keys</span>) </span>{
            <span class="hljs-keyword">if</span>(!keys) {
                <span class="hljs-keyword">var</span> embeddingKeys = _.filter(_.keys(<span class="hljs-keyword">this</span>.embeddings), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                    <span class="hljs-keyword">return</span> !<span class="hljs-keyword">this</span>.get(key) || (!<span class="hljs-keyword">this</span>.get(key).isSyncing &amp;&amp; !<span class="hljs-keyword">this</span>.get(key).isSynced);
                }, <span class="hljs-keyword">this</span>);
                <span class="hljs-keyword">var</span> referencesKeys = _.filter(_.keys(<span class="hljs-keyword">this</span>.references), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.get(key) &amp;&amp; (!<span class="hljs-keyword">this</span>.get(key).isSyncing &amp;&amp; !<span class="hljs-keyword">this</span>.get(key).isSynced);
                }, <span class="hljs-keyword">this</span>);

                keys = _.union(embeddingKeys, referencesKeys);
            }

            <span class="hljs-keyword">if</span>(_.isString(keys)) {
                keys = [keys];
            }

            <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;keys.length; i++) {
                <span class="hljs-keyword">var</span> key = keys[i];

                <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.embeddings[key] &amp;&amp; !<span class="hljs-keyword">this</span>.references[key]) {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid relationship key '"</span> + key + <span class="hljs-string">"'"</span>);
                }</pre></div></div>
            
        </li>
        
        
        <li id="section-37">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-37">&#182;</a>
              </div>
              <p>init embeddings</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.get(key) &amp;&amp; <span class="hljs-keyword">this</span>.embeddings[key]) {
                    <span class="hljs-keyword">var</span> RelClass = resolveRelClass(<span class="hljs-keyword">this</span>.embeddings[key]);
                    <span class="hljs-keyword">this</span>.set(key, <span class="hljs-keyword">new</span> RelClass());
                }

                <span class="hljs-keyword">var</span> relatedObject = <span class="hljs-keyword">this</span>.get(key);
                <span class="hljs-keyword">if</span>(relatedObject &amp;&amp; !relatedObject.isSyncing &amp;&amp; !_.contains(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, relatedObject)) {
                    <span class="hljs-keyword">this</span>._relatedObjectsToFetch.push(relatedObject);
                }
            }
            <span class="hljs-keyword">this</span>._fetchRelatedObjects();
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-38">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-38">&#182;</a>
              </div>
              <p>Sets the parent of an embedded object
If the optional keyInParent parameter is omitted, is is automatically detected</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        setParent: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">parent, keyInParent</span>) </span>{
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
            <span class="hljs-keyword">this</span>.keyInParent = keyInParent || _.find(_.keys(parent.embeddings), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">return</span> parent.get(key) === self;
            });
            <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.keyInParent) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"A key for the embedding in the parent must be specified as it could not be detected automatically."</span>);
            }

            <span class="hljs-keyword">this</span>.parent = parent;
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent.get(<span class="hljs-keyword">this</span>.keyInParent) !== <span class="hljs-keyword">this</span>) {
                <span class="hljs-keyword">this</span>.parent.set(<span class="hljs-keyword">this</span>.keyInParent, <span class="hljs-keyword">this</span>);
            }

            <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"embedded"</span>, <span class="hljs-keyword">this</span>, parent, keyInParent);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-39">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-39">&#182;</a>
              </div>
              <p>Override #previous to add support for getting previous values of references and embeddings
in “change” events</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        previous: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) </span>{
            <span class="hljs-keyword">var</span> result = BackboneBase.Model.prototype.previous.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
            <span class="hljs-keyword">if</span>(result) <span class="hljs-keyword">return</span> result;

            <span class="hljs-keyword">if</span> (attr === <span class="hljs-literal">null</span> || !<span class="hljs-keyword">this</span>._previousRelatedObjects) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._previousRelatedObjects[attr];
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-40">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-40">&#182;</a>
              </div>
              <p>Override #toJSON to add support for inlining JSON representations of related objects
in the JSON of this model. The related objects to be inlined can be specified via the
<code>inlineJSON</code> property or option.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        toJSON: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) </span>{
            options = options || {};
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
            <span class="hljs-keyword">var</span> json = BackboneBase.Model.prototype.toJSON.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);

            <span class="hljs-keyword">var</span> inlineJSON = _.uniq(_.compact(_.flatten(
                _.union([options.inlineJSON], [_.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">"inlineJSON"</span>)])
            )));

            _.each(inlineJSON, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">var</span> obj = self;
                <span class="hljs-keyword">var</span> path = key.split(<span class="hljs-string">"."</span>),
                    nestedJson = json;
                <span class="hljs-keyword">while</span>(obj &amp;&amp; path.length &gt; <span class="hljs-number">0</span> &amp;&amp; _.isFunction(obj.toJSON)) {
                    key = path.shift();
                    obj = obj.get(key);
                    <span class="hljs-keyword">if</span>(obj &amp;&amp; _.isFunction(obj.toJSON)) {</pre></div></div>
            
        </li>
        
        
        <li id="section-41">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-41">&#182;</a>
              </div>
              <p>nest JSON represention ob embedded object into the hierarchy</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        nestedJson[key] = obj.toJSON();
                        nestedJson = nestedJson[key];
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(obj===<span class="hljs-literal">null</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-42">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-42">&#182;</a>
              </div>
              <p>if an embedded object was unset, i.e., set to null, we have to
notify the server by nesting a null value into the JSON hierarchy</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        nestedJson[key] = <span class="hljs-literal">null</span>;
                    }
                }
            });
            <span class="hljs-keyword">return</span> json;
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-43">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-43">&#182;</a>
              </div>
              <p>Override #fetch to add support for auto-fetching of embedded objects</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        fetch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">var</span> result = BackboneBase.Model.prototype.fetch.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
            <span class="hljs-keyword">this</span>._autoFetchEmbeddings();
            <span class="hljs-keyword">return</span> result;
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-44">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-44">&#182;</a>
              </div>
              <p>Override #sync to force PUT method when creating embedded models</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        sync: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method, obj, options</span>) </span>{
            <span class="hljs-keyword">this</span>._beforeSync();
            options = wrapOptionsCallbacks(<span class="hljs-keyword">this</span>._afterSyncBeforeSet.bind(<span class="hljs-keyword">this</span>), options);
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent &amp;&amp; method === <span class="hljs-string">"create"</span>) method = <span class="hljs-string">"update"</span>; <span class="hljs-comment">// always PUT embedded models</span>
            <span class="hljs-keyword">if</span>(options.forceMethod) {
                method = options.forceMethod;
            }
            <span class="hljs-keyword">return</span> BackboneBase.Model.prototype.sync.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-45">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-45">&#182;</a>
              </div>
              <p>PRIVATE METHODS</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        _setEmbedding: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, value, options, changes</span>) </span>{

            <span class="hljs-keyword">var</span> RelClass = resolveRelClass(<span class="hljs-keyword">this</span>.embeddings[key]);
            <span class="hljs-keyword">var</span> current = <span class="hljs-keyword">this</span>.relatedObjects[key];

            <span class="hljs-keyword">if</span>(options.unset || options.clear) {
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.relatedObjects[key];
            }
        
            <span class="hljs-keyword">if</span>(!options.unset &amp;&amp; value &amp;&amp; value !== current) {

                <span class="hljs-keyword">if</span>(value._representsToMany || value._representsToOne) {</pre></div></div>
            
        </li>
        
        
        <li id="section-46">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-46">&#182;</a>
              </div>
              <p>a model object is directly assigned
set its parent</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>.relatedObjects[key] = value;
                    <span class="hljs-keyword">this</span>.relatedObjects[key].setParent(<span class="hljs-keyword">this</span>, key);
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.relatedObjects[key]) {</pre></div></div>
            
        </li>
        
        
        <li id="section-47">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-47">&#182;</a>
              </div>
              <p>|| (!_.isArray(value) &amp;&amp; !this.relatedObjects[key].isNew() &amp;&amp; this.relatedObjects[key].id !== value[this.relatedObjects[key].idAttribute])) {
first assignment of an embedded model        //or assignment of an embedded model with a different ID
create embedded model and set its parent</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>.relatedObjects[key] = <span class="hljs-keyword">new</span> RelClass(value, options);
                    <span class="hljs-keyword">this</span>.relatedObjects[key].setParent(<span class="hljs-keyword">this</span>, key);
                } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-48">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-48">&#182;</a>
              </div>
              <p>update embedded model’s attributes</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                    <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.relatedObjects[key]._representsToMany) {
                        <span class="hljs-keyword">this</span>.relatedObjects[key][options.reset ? <span class="hljs-string">'reset'</span> : <span class="hljs-string">'set'</span>](value, options);
                    } <span class="hljs-keyword">else</span> {
                        <span class="hljs-keyword">if</span>(options.parse) {
                            value = <span class="hljs-keyword">this</span>.relatedObjects[key].parse(value, options);
                        }
                        <span class="hljs-keyword">this</span>.relatedObjects[key].set(value, options);
                    }
                }

            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(!options.unset) {</pre></div></div>
            
        </li>
        
        
        <li id="section-49">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-49">&#182;</a>
              </div>
              <p>set new embedded object or null/undefined</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">this</span>.relatedObjects[key] = value;
            }

            <span class="hljs-keyword">if</span>(current !== <span class="hljs-keyword">this</span>.relatedObjects[key]) {
                changes.push(key);

                <span class="hljs-keyword">this</span>._listenToRelatedObject(key, current);</pre></div></div>
            
        </li>
        
        
        <li id="section-50">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-50">&#182;</a>
              </div>
              <p>unset current’s parent property</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(current) {
                    current.parent = <span class="hljs-literal">null</span>;
                }
            }
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>._previousRelatedObjects[key] !== <span class="hljs-keyword">this</span>.relatedObjects[key]) {
                <span class="hljs-keyword">this</span>.changed[key] = <span class="hljs-keyword">this</span>.relatedObjects[key];
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.changed[key];
            }
        },

        _setReference: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, value, options, changes</span>) </span>{
            <span class="hljs-keyword">var</span> RelClass = resolveRelClass(<span class="hljs-keyword">this</span>.references[key]),
                idRef = <span class="hljs-keyword">this</span>.referenceAttributeName(key);
            <span class="hljs-keyword">var</span> current = <span class="hljs-keyword">this</span>.relatedObjects[key],
                currentId = <span class="hljs-keyword">this</span>.attributes[idRef];

            <span class="hljs-keyword">if</span>(options.unset || options.clear) {
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.relatedObjects[key];
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.attributes[idRef];
            }

            <span class="hljs-keyword">if</span>(!options.unset &amp;&amp; value!==<span class="hljs-literal">undefined</span> &amp;&amp; value!==<span class="hljs-literal">null</span>) {
                <span class="hljs-keyword">if</span>(RelClass.prototype._representsToOne) {</pre></div></div>
            
        </li>
        
        
        <li id="section-51">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-51">&#182;</a>
              </div>
              <p>handling to-one relation</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>._setToOneReference(key, RelClass, value, options);
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(RelClass.prototype._representsToMany) {</pre></div></div>
            
        </li>
        
        
        <li id="section-52">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-52">&#182;</a>
              </div>
              <p>handling to-many relation</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>._setToManyReference(key, RelClass, value, options);
                }
                <span class="hljs-keyword">this</span>._ensureIdReference(idRef, key);
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(!options.unset) {</pre></div></div>
            
        </li>
        
        
        <li id="section-53">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-53">&#182;</a>
              </div>
              <p>set <code>undefined</code> or <code>null</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">this</span>.relatedObjects[key] = value;
                <span class="hljs-keyword">this</span>.attributes[idRef] = value;
            }

            <span class="hljs-keyword">if</span>(!_.isEqual(currentId, <span class="hljs-keyword">this</span>.attributes[idRef])) {
                changes.push(idRef);
            }
            <span class="hljs-keyword">if</span>(current !== <span class="hljs-keyword">this</span>.relatedObjects[key]) {
                changes.push(key);
                <span class="hljs-keyword">this</span>._listenToRelatedObject(key, current);
            }

            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>._previousRelatedObjects[key] !== <span class="hljs-keyword">this</span>.relatedObjects[key]) {
                <span class="hljs-keyword">this</span>.changed[key] = <span class="hljs-keyword">this</span>.relatedObjects[key];
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.changed[key];
            }
            <span class="hljs-keyword">if</span>(!_.isEqual(<span class="hljs-keyword">this</span>._previousAttributes[idRef], <span class="hljs-keyword">this</span>.attributes[idRef])) {
                <span class="hljs-keyword">this</span>.changed[idRef] = <span class="hljs-keyword">this</span>.attributes[idRef];
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.changed[idRef];
            }

        },

        _ensureIdReference: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">idRef, refKey</span>) </span>{
            <span class="hljs-keyword">var</span> relatedObject = <span class="hljs-keyword">this</span>.relatedObjects[refKey];

            <span class="hljs-keyword">if</span>(relatedObject._representsToOne) {</pre></div></div>
            
        </li>
        
        
        <li id="section-54">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-54">&#182;</a>
              </div>
              <p>if the relatedObject is new, i.e., it doesn’t have an ID yet
we need to update the reference as soon as the referenced objects
got assigned an ID</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                <span class="hljs-keyword">if</span>(relatedObject.isNew()) {
                    <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.attributes[idRef]) {
                        <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.attributes[idRef];
                    }
                    relatedObject.once(<span class="hljs-string">"change:"</span> + (relatedObject.idAttribute||<span class="hljs-string">"id"</span>), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                        <span class="hljs-keyword">this</span>.set(idRef, relatedObject.id);
                    }, <span class="hljs-keyword">this</span>);
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-keyword">this</span>.attributes[idRef] = relatedObject.id;
                }

            } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-55">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-55">&#182;</a>
              </div>
              <p>if any one of the referenced objects is new,
we need to update the ID ref array as soon as that item
got assigned an ID</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                <span class="hljs-keyword">var</span> atLeastOneItemIsNew = <span class="hljs-literal">false</span>,
                    idAttr;
                <span class="hljs-keyword">this</span>.attributes[idRef] = _.compact(relatedObject.map(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">m</span>) </span>{
                    <span class="hljs-keyword">if</span>(m.isNew()) {
                        atLeastOneItemIsNew = <span class="hljs-literal">true</span>;
                        idAttr = m.idAttribute || <span class="hljs-string">"id"</span>;
                        <span class="hljs-keyword">return</span> <span class="hljs-literal">undefined</span>;
                    } <span class="hljs-keyword">else</span> {
                        <span class="hljs-keyword">return</span> m.id;
                    }
                }));
                <span class="hljs-keyword">if</span>(atLeastOneItemIsNew) {
                    relatedObject.once(<span class="hljs-string">"change:"</span> + idAttr, <span class="hljs-keyword">this</span>._ensureIdReference.bind(<span class="hljs-keyword">this</span>, idRef, refKey));
                }

            }
        },

        _setToOneReference: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, RelClass, value, options</span>) </span>{
            <span class="hljs-keyword">var</span> relatedObject = <span class="hljs-keyword">this</span>.relatedObjects[key];

            <span class="hljs-keyword">var</span> id = value[RelClass.prototype.idAttribute||<span class="hljs-string">"id"</span>] || value;</pre></div></div>
            
        </li>
        
        
        <li id="section-56">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-56">&#182;</a>
              </div>
              <p>reset relatedObject if the ID reference changed
if the current related object does not yet have an id and the new value is side-loaded
data, do not reset, but assign the new id to the current related object</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(relatedObject &amp;&amp; relatedObject.id !== id &amp;&amp; (relatedObject[relatedObject.idAttribute||<span class="hljs-string">"id"</span>] || !(value <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>))) {
                relatedObject = <span class="hljs-literal">undefined</span>;
            }

            <span class="hljs-keyword">if</span>(value._representsToOne) {</pre></div></div>
            
        </li>
        
        
        <li id="section-57">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-57">&#182;</a>
              </div>
              <p>directly assign a model</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(value===relatedObject) <span class="hljs-keyword">return</span>;
                relatedObject = value;
                <span class="hljs-keyword">this</span>.relatedObjects[key] = relatedObject;
                <span class="hljs-keyword">return</span>;
            }

            <span class="hljs-keyword">if</span>(value <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-58">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-58">&#182;</a>
              </div>
              <p>if the related model data is side-loaded,
create/update the related model instance</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                <span class="hljs-keyword">if</span>(relatedObject) {
                    <span class="hljs-keyword">if</span>(options.parse) {
                        value = relatedObject.parse(value, options);
                    }
                    relatedObject.set(value, options);
                } <span class="hljs-keyword">else</span> {
                    relatedObject = <span class="hljs-keyword">new</span> RelClass(value, options);
                }

                relatedObject.isSynced = <span class="hljs-literal">true</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-59">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-59">&#182;</a>
              </div>
              <p>remove side-loaded object from the models to fetch</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(relatedObject !== <span class="hljs-keyword">this</span>)
                    <span class="hljs-keyword">this</span>._relatedObjectsToFetch = _.without(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, relatedObject);

            } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-60">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-60">&#182;</a>
              </div>
              <p>if only an ID reference is provided,
instantiate the model</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                <span class="hljs-keyword">if</span>(!relatedObject) {
                    <span class="hljs-keyword">var</span> attrs = {};
                    attrs[RelClass.prototype.idAttribute||<span class="hljs-string">"id"</span>] = id;
                    relatedObject = <span class="hljs-keyword">new</span> RelClass(attrs, options);</pre></div></div>
            
        </li>
        
        
        <li id="section-61">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-61">&#182;</a>
              </div>
              <p>auto-fetch related model if its url can be built</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">var</span> autoFetch = <span class="hljs-keyword">this</span>.autoFetchRelated === <span class="hljs-literal">true</span> ||
                        (_.isArray(<span class="hljs-keyword">this</span>.autoFetchRelated) &amp;&amp; _.contains(<span class="hljs-keyword">this</span>.autoFetchRelated, key));
                    <span class="hljs-keyword">var</span> url;
                    <span class="hljs-keyword">try</span> {
                        url = _.result(relatedObject, <span class="hljs-string">"url"</span>);
                    } <span class="hljs-keyword">catch</span>(e) {
                        <span class="hljs-keyword">if</span>(autoFetch &amp;&amp; <span class="hljs-built_in">console</span> &amp;&amp; _.isFunction(<span class="hljs-built_in">console</span>.warn)) {
                            <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Could not build url to auto-fetch referenced model for key '"</span> + key +<span class="hljs-string">"'"</span>, e.stack);
                        }
                    }
                    <span class="hljs-keyword">if</span>(autoFetch &amp;&amp; url &amp;&amp; !relatedObject.isSynced &amp;&amp; !relatedObject.isSyncing &amp;&amp; !_.contains(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, relatedObject)) {
                        <span class="hljs-keyword">this</span>._relatedObjectsToFetch.push(relatedObject);
                    }
                }

            }

            <span class="hljs-keyword">this</span>.relatedObjects[key] = relatedObject;
        },

        _setToManyReference: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, RelClass, value, options</span>) </span>{
            <span class="hljs-keyword">var</span> ItemModel = RelClass.prototype.model;

            <span class="hljs-keyword">var</span> relatedObject = <span class="hljs-keyword">this</span>.relatedObjects[key];

            <span class="hljs-keyword">if</span>(value._representsToMany) {</pre></div></div>
            
        </li>
        
        
        <li id="section-62">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-62">&#182;</a>
              </div>
              <p>a collection model is directly assigned</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
                <span class="hljs-keyword">if</span>(value===relatedObject) <span class="hljs-keyword">return</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-63">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-63">&#182;</a>
              </div>
              <p>teardown relation to old collection</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(relatedObject) {
                    relatedObject.parent = <span class="hljs-literal">undefined</span>; <span class="hljs-comment">// <span class="hljs-doctag"><span class="hljs-keyword">TODO</span></span> get rid of this here!!!</span>
                }</pre></div></div>
            
        </li>
        
        
        <li id="section-64">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-64">&#182;</a>
              </div>
              <p>setup relation to the new collection</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                relatedObject = value;
                relatedObject.parent = <span class="hljs-keyword">this</span>; <span class="hljs-comment">// <span class="hljs-doctag"><span class="hljs-keyword">TODO</span></span> get rid of this here!!!</span>
                <span class="hljs-keyword">this</span>.relatedObjects[key] = relatedObject;
                <span class="hljs-keyword">return</span>;
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-65">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-65">&#182;</a>
              </div>
              <p>expect an array of IDs or model json objects</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(!_.isArray(value)) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Got an unexpected value to set reference '"</span> + key + <span class="hljs-string">"'"</span>);
            }

            <span class="hljs-keyword">if</span>(!relatedObject) {
                relatedObject = <span class="hljs-keyword">new</span> RelClass([], {parent: <span class="hljs-keyword">this</span>});
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-66">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-66">&#182;</a>
              </div>
              <p>iterate all related items and get/initialize/fetch the model objects</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> modelArray = _.map(value, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">itemData</span>) </span>{

                <span class="hljs-keyword">var</span> id = itemData.id || itemData;</pre></div></div>
            
        </li>
        
        
        <li id="section-67">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-67">&#182;</a>
              </div>
              <p>try to get the related model from the current relatedObject collection</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">var</span> item = relatedObject.get(id);

                <span class="hljs-keyword">if</span>(itemData <span class="hljs-keyword">instanceof</span> Backbone.Model) {
                    <span class="hljs-keyword">return</span> itemData;
                }

                <span class="hljs-keyword">if</span>(itemData <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Object</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-68">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-68">&#182;</a>
              </div>
              <p>if the related model data is sideloaded,
create/update the related model instance</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(item) {
                        <span class="hljs-keyword">if</span>(options.parse) {
                            itemData = item.parse(itemData, options);
                        }
                        item.set(itemData, options);
                    } <span class="hljs-keyword">else</span> {
                        item = <span class="hljs-keyword">new</span> ItemModel(itemData, options);
                    }

                    item.isSynced = <span class="hljs-literal">true</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-69">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-69">&#182;</a>
              </div>
              <p>remove side-loaded object from the models to fetch</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(item !== <span class="hljs-keyword">this</span>) {
                        <span class="hljs-keyword">this</span>._relatedObjectsToFetch = _.without(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, item);
                    }
                } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-70">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-70">&#182;</a>
              </div>
              <p>if only an ID reference is provided
and the relation could not be resolved to an already loaded model,
instantiate the model</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">if</span>(!item) {
                        <span class="hljs-keyword">var</span> attrs = {};
                        attrs[ItemModel.prototype.idAttribute||<span class="hljs-string">"id"</span>] = id;
                        item = <span class="hljs-keyword">new</span> ItemModel(attrs, _.extend({}, options, { parse: <span class="hljs-literal">undefined</span> }));</pre></div></div>
            
        </li>
        
        
        <li id="section-71">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-71">&#182;</a>
              </div>
              <p>auto-fetch related model if its url can be built</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                        <span class="hljs-keyword">var</span> autoFetch = <span class="hljs-keyword">this</span>.autoFetchRelated === <span class="hljs-literal">true</span> ||
                            (_.isArray(<span class="hljs-keyword">this</span>.autoFetchRelated) &amp;&amp; _.contains(<span class="hljs-keyword">this</span>.autoFetchRelated, key));
                        <span class="hljs-keyword">var</span> url;
                        <span class="hljs-keyword">try</span> {
                            url = _.result(item, <span class="hljs-string">"url"</span>);
                        } <span class="hljs-keyword">catch</span>(e) {
                            <span class="hljs-keyword">if</span>(autoFetch &amp;&amp; <span class="hljs-built_in">console</span> &amp;&amp; _.isFunction(<span class="hljs-built_in">console</span>.warn)) {
                                <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Could not build url to auto-fetch referenced model for key '"</span> + key + <span class="hljs-string">"'"</span>, e);
                            }
                        }
                        <span class="hljs-keyword">if</span>(autoFetch &amp;&amp; url &amp;&amp; !item.isSynced &amp;&amp; !item.isSyncing &amp;&amp; !_.contains(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, item)) {
                            <span class="hljs-keyword">this</span>._relatedObjectsToFetch.push(item);
                        }
                    }
                }

                <span class="hljs-keyword">return</span> item;
            }, <span class="hljs-keyword">this</span>);</pre></div></div>
            
        </li>
        
        
        <li id="section-72">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-72">&#182;</a>
              </div>
              <p>important: do not merge into existing models as this might cause running into endless set loops for circular relations
merging of related model items’ attributes is already done in the _.map() above</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            relatedObject.set(modelArray, {merge:<span class="hljs-literal">false</span>});

            <span class="hljs-keyword">this</span>.relatedObjects[key] = relatedObject;
        },

        _listenToRelatedObject: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, current</span>) </span>{

            <span class="hljs-keyword">if</span>(current) {</pre></div></div>
            
        </li>
        
        
        <li id="section-73">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-73">&#182;</a>
              </div>
              <p>stop propagating ‘deepchange’ of current related object</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">this</span>.stopListening(current, <span class="hljs-string">'deepchange'</span>, <span class="hljs-keyword">this</span>._propagateDeepChange);</pre></div></div>
            
        </li>
        
        
        <li id="section-74">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-74">&#182;</a>
              </div>
              <p>stop listening to destroy and ID change events</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(current._representsToOne) {
                    <span class="hljs-keyword">this</span>.stopListening(current, <span class="hljs-string">'destroy'</span>, <span class="hljs-keyword">this</span>._relatedObjectDestroyHandler);
                    <span class="hljs-keyword">this</span>.stopListening(current, <span class="hljs-string">'change:'</span> + (current.idAttribute || <span class="hljs-string">"id"</span>), <span class="hljs-keyword">this</span>._updateIdRefFor[key]);
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-keyword">this</span>.stopListening(current, <span class="hljs-string">'add remove reset change:'</span> + (current.idAttribute || <span class="hljs-string">"id"</span>), <span class="hljs-keyword">this</span>._updateIdRefFor[key]);
                }
            }</pre></div></div>
            
        </li>
        
        
        <li id="section-75">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-75">&#182;</a>
              </div>
              <p>start propagating ‘deepchange’ of new related object</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.relatedObjects[key]) {
                <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.relatedObjects[key], <span class="hljs-string">'deepchange'</span>, <span class="hljs-keyword">this</span>._propagateDeepChange);
                <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.relatedObjects[key]._representsToOne) {</pre></div></div>
            
        </li>
        
        
        <li id="section-76">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-76">&#182;</a>
              </div>
              <p>listen to destroy to unset references</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.relatedObjects[key], <span class="hljs-string">'destroy'</span>, <span class="hljs-keyword">this</span>._relatedObjectDestroyHandler);</pre></div></div>
            
        </li>
        
        
        <li id="section-77">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-77">&#182;</a>
              </div>
              <p>listen to changes of the ID to update ref</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>._updateIdRefFor[key] = <span class="hljs-keyword">this</span>._updateIdRefFor[key] || <span class="hljs-keyword">this</span>._updateIdRef.bind(<span class="hljs-keyword">this</span>, key);
                    <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.relatedObjects[key], <span class="hljs-string">'change:'</span> + (<span class="hljs-keyword">this</span>.relatedObjects[key].idAttribute || <span class="hljs-string">"id"</span>), <span class="hljs-keyword">this</span>._updateIdRefFor[key]);
                } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-78">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-78">&#182;</a>
              </div>
              <p>listen to changes in the of item IDs and collection manipulations to update ID ref array</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                    <span class="hljs-keyword">this</span>._updateIdRefFor[key] = <span class="hljs-keyword">this</span>._updateIdRefFor[key] || <span class="hljs-keyword">this</span>._updateIdRef.bind(<span class="hljs-keyword">this</span>, key);
                    <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.relatedObjects[key], <span class="hljs-string">'add remove reset change:'</span> + (<span class="hljs-keyword">this</span>.relatedObjects[key].idAttribute || <span class="hljs-string">"id"</span>), <span class="hljs-keyword">this</span>._updateIdRefFor[key]);
                }
            }
        },

        _updateIdRef: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.references[key]) {
                <span class="hljs-keyword">var</span> idRef = <span class="hljs-keyword">this</span>.referenceAttributeName(key);
                <span class="hljs-keyword">this</span>._ensureIdReference(idRef, key);
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"change:"</span> + idRef, <span class="hljs-keyword">this</span>, <span class="hljs-keyword">this</span>.get(idRef), {});
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"change"</span>, <span class="hljs-keyword">this</span>, {});
            }
        },

        _autoFetchEmbeddings: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">onlyUndefinedEmbeddings</span>) </span>{
            <span class="hljs-keyword">var</span> embeddingsKeys = _.keys(<span class="hljs-keyword">this</span>.embeddings);
            <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;embeddingsKeys.length; i++) {
                <span class="hljs-keyword">var</span> key = embeddingsKeys[i];
                <span class="hljs-keyword">var</span> autoFetch = <span class="hljs-keyword">this</span>.autoFetchRelated === <span class="hljs-literal">true</span> ||
                        (_.isArray(<span class="hljs-keyword">this</span>.autoFetchRelated) &amp;&amp; _.contains(<span class="hljs-keyword">this</span>.autoFetchRelated, key));
                <span class="hljs-keyword">if</span>(autoFetch) {
                    <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.get(key)) {
                        <span class="hljs-keyword">var</span> RelClass = resolveRelClass(<span class="hljs-keyword">this</span>.embeddings[key]);
                        <span class="hljs-keyword">this</span>.set(key, <span class="hljs-keyword">new</span> RelClass());
                    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(onlyUndefinedEmbeddings) {
                        <span class="hljs-keyword">continue</span>;
                    }
                    <span class="hljs-keyword">var</span> relatedObject = <span class="hljs-keyword">this</span>.get(key);
                    <span class="hljs-keyword">if</span>(!relatedObject.isSyncing &amp;&amp; !_.contains(<span class="hljs-keyword">this</span>._relatedObjectsToFetch, relatedObject)) {
                        <span class="hljs-keyword">this</span>._relatedObjectsToFetch.push(relatedObject);
                    }
                }
            }
            <span class="hljs-keyword">this</span>._fetchRelatedObjects();
        },

        _beforeSync: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>.isSyncing = <span class="hljs-literal">true</span>;</pre></div></div>
            
        </li>
        
        
        <li id="section-79">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-79">&#182;</a>
              </div>
              <p>make sure that “deepsync” is always triggered after “sync”</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">this</span>._relatedObjectsToFetch.push(<span class="hljs-keyword">this</span>);
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
            <span class="hljs-keyword">var</span> syncCb = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                self._relatedObjectFetchSuccessHandler(self);
                self.off(<span class="hljs-string">"error"</span>, errorCb);
            };
            <span class="hljs-keyword">var</span> errorCb = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                self._relatedObjectsToFetch.splice(self._relatedObjectsToFetch.indexOf(self), <span class="hljs-number">1</span>);
                self.off(<span class="hljs-string">"sync"</span>, syncCb);
            };
            <span class="hljs-keyword">this</span>.once(<span class="hljs-string">"sync"</span>, syncCb);
            <span class="hljs-keyword">this</span>.once(<span class="hljs-string">"error"</span>, errorCb);
        },

        _afterSyncBeforeSet: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>.isSynced = <span class="hljs-literal">true</span>;
            <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.isSyncing;
        },

        _propagateDeepChange: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">changedModelOrCollection, opts</span>) </span>{</pre></div></div>
            
        </li>
        
        
        <li id="section-80">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-80">&#182;</a>
              </div>
              <p>make sure that ‘deepchange’ is only triggered once, also when set operations are nested</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span>(_.contains(<span class="hljs-keyword">this</span>._deepChangePropagatedFor, opts.setOriginId)) {
                <span class="hljs-keyword">return</span>;
            }
            <span class="hljs-keyword">this</span>._deepChangePropagatedFor.push(opts.setOriginId);
            <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange'</span>, changedModelOrCollection, opts);
            changedModelOrCollection.once(<span class="hljs-string">'deepchange_propagated'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange_propagated'</span>, changedModelOrCollection, opts);
            }, <span class="hljs-keyword">this</span>);
        },

        _fetchRelatedObjects: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-keyword">this</span>._relatedObjectsToFetch.length; i++) {
                <span class="hljs-keyword">var</span> model = <span class="hljs-keyword">this</span>._relatedObjectsToFetch[i];
                <span class="hljs-keyword">if</span>(model===<span class="hljs-keyword">this</span>) <span class="hljs-keyword">continue</span>; <span class="hljs-comment">// do not fetch again while setting</span></pre></div></div>
            
        </li>
        
        
        <li id="section-81">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-81">&#182;</a>
              </div>
              <p>test whether fetching has already been triggered by another relation</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">if</span>(model.isSyncing) {
                    model.once(<span class="hljs-string">"sync"</span>, <span class="hljs-keyword">this</span>._relatedObjectFetchSuccessHandler.bind(<span class="hljs-keyword">this</span>, model));
                    <span class="hljs-keyword">continue</span>;
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(model.isSynced) {
                    <span class="hljs-keyword">this</span>._relatedObjectFetchSuccessHandler(model);
                    <span class="hljs-keyword">continue</span>;
                }

                model.fetch({
                    success: <span class="hljs-keyword">this</span>._relatedObjectFetchSuccessHandler.bind(<span class="hljs-keyword">this</span>),
                    error: <span class="hljs-keyword">this</span>._relatedObjectFetchErrorHandler.bind(<span class="hljs-keyword">this</span>),
                    isAutoFetch: <span class="hljs-literal">true</span>
                });
            }
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-82">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-82">&#182;</a>
              </div>
              <p>This callback is executed after every successful fetch of related objects after
these have been set as a reference auto-fetched as an embedding. It is responsible
for eventually triggering the ‘deepsync’ event.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        _relatedObjectFetchSuccessHandler: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{
            <span class="hljs-keyword">this</span>._relatedObjectsToFetch.splice(<span class="hljs-keyword">this</span>._relatedObjectsToFetch.indexOf(obj), <span class="hljs-number">1</span>);
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>._relatedObjectsToFetch.length === <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"deepsync"</span>, <span class="hljs-keyword">this</span>);
            }
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-83">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-83">&#182;</a>
              </div>
              <p>propagate errors when automatically fetching related models</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        _relatedObjectFetchErrorHandler: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj, resp, options</span>) </span>{
            <span class="hljs-keyword">this</span>._relatedObjectsToFetch.splice(<span class="hljs-keyword">this</span>._relatedObjectsToFetch.indexOf(obj), <span class="hljs-number">1</span>);
            <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'error'</span>, obj, resp, options);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-84">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-84">&#182;</a>
              </div>
              <p>This callback ensures that relations are unset, when a related object is destroyed</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        _relatedObjectDestroyHandler: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">destroyedObject</span>) </span>{
            _.each(<span class="hljs-keyword">this</span>.relatedObjects, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">relObj, key</span>) </span>{
                <span class="hljs-keyword">if</span>(relObj === destroyedObject) {
                    <span class="hljs-keyword">this</span>.unset(key);
                }
            }, <span class="hljs-keyword">this</span>);
        },

        _representsToOne: <span class="hljs-literal">true</span>

    });

    Backbone.Collection = BackboneBase.Collection.extend({

        constructor: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{

            <span class="hljs-keyword">var</span> triggerOriginalDeepChange = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) </span>{
                options = options || {};</pre></div></div>
            
        </li>
        
        
        <li id="section-85">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-85">&#182;</a>
              </div>
              <p>Trigger original ‘deepchange’ event, which will be propagated through the related object graph</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>                <span class="hljs-keyword">var</span> originId = options.setOriginId || _.uniqueId();
                <span class="hljs-keyword">this</span>._deepChangePropagatedFor.push(originId);
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange'</span>, <span class="hljs-keyword">this</span>, _.extend({ setOriginId: originId }, options));
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">'deepchange_propagated'</span>, <span class="hljs-keyword">this</span>, _.extend({ setOriginId: originId }, options));
            }.bind(<span class="hljs-keyword">this</span>);

            <span class="hljs-keyword">this</span>.on(<span class="hljs-string">'add remove'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">model, collection, options</span>) </span>{
                triggerOriginalDeepChange(options);
            });
            <span class="hljs-keyword">this</span>.on(<span class="hljs-string">'reset'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">collection, options</span>) </span>{
                triggerOriginalDeepChange(options);
            });
            <span class="hljs-keyword">this</span>.on(<span class="hljs-string">'sort'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">collection, options</span>) </span>{
               triggerOriginalDeepChange(options);
            });

            <span class="hljs-keyword">return</span> BackboneBase.Collection.prototype.constructor.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
        },

        url: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">var</span> base = _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'urlRoot'</span>);
            <span class="hljs-keyword">if</span>(base) {
                <span class="hljs-keyword">return</span> base;
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent) {
                <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent.isNew() &amp;&amp; !<span class="hljs-keyword">this</span>.parent.parent) {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Could not get the parent model's URL as it has not been saved yet."</span>);
                }
                base = _.result(<span class="hljs-keyword">this</span>.parent, <span class="hljs-string">'url'</span>);
                <span class="hljs-keyword">var</span> suffix = _.result(<span class="hljs-keyword">this</span>, <span class="hljs-string">'urlSuffix'</span>);
                <span class="hljs-keyword">if</span>(base &amp;&amp; suffix) {
                    <span class="hljs-keyword">return</span> base.replace(<span class="hljs-regexp">/([^\/])$/</span>, <span class="hljs-string">'$1/'</span>) + suffix.replace(<span class="hljs-regexp">/(\/?)(.*)/</span>, <span class="hljs-string">'$2'</span>);
                }
            }

            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Could not build url for the collection'</span>);
        },

        urlSuffix: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>,
                parent = <span class="hljs-keyword">this</span>.parent;
            <span class="hljs-keyword">return</span> parent &amp;&amp; _.find(_.keys(parent.embeddings), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">return</span> parent.get(key) === self;
            });
        },

        set: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>._deepChangePropagatedFor = [];
            <span class="hljs-keyword">return</span> BackboneBase.Collection.prototype.set.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-86">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-86">&#182;</a>
              </div>
              <p>Sets the parent for an embedded collection
If the optional keyInParent parameter is omitted, is is automatically detected</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        setParent: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">parent, keyInParent</span>) </span>{
            <span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
            <span class="hljs-keyword">this</span>.keyInParent = keyInParent || _.find(_.keys(parent.embeddings), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
                <span class="hljs-keyword">return</span> parent.get(key) === self;
            });
            <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">this</span>.keyInParent) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"A key for the embedding in the parent must be specified as it could not be detected automatically."</span>);
            }

            <span class="hljs-keyword">this</span>.parent = parent;
            <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.parent.get(<span class="hljs-keyword">this</span>.keyInParent) !== <span class="hljs-keyword">this</span>) {
                <span class="hljs-keyword">this</span>.parent.set(<span class="hljs-keyword">this</span>.keyInParent, <span class="hljs-keyword">this</span>);
            }

            <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"embedded"</span>, <span class="hljs-keyword">this</span>, parent, keyInParent);
        },

        sync: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>._beforeSync();</pre></div></div>
            
        </li>
        
        
        <li id="section-87">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-87">&#182;</a>
              </div>
              <p>options = wrapOptionsCallbacks(this._afterSetBeforeTrigger, options);</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">return</span> BackboneBase.Collection.prototype.sync.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
        },

        fetch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) </span>{
            options = wrapOptionsCallbacks(<span class="hljs-keyword">this</span>._afterSetBeforeTrigger.bind(<span class="hljs-keyword">this</span>), options);</pre></div></div>
            
        </li>
        
        
        <li id="section-88">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-88">&#182;</a>
              </div>
              <p>auto-fetch embeddings of items
this.once(“sync”, function() {
   this.each(function(item) {
       item._autoFetchEmbeddings();
   });
}, this);</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
            <span class="hljs-keyword">return</span> BackboneBase.Collection.prototype.fetch.apply(<span class="hljs-keyword">this</span>, [options]);
        },</pre></div></div>
            
        </li>
        
        
        <li id="section-89">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-89">&#182;</a>
              </div>
              <p>PRIVATE METHODS</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
        _beforeSync: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>.isSyncing = <span class="hljs-literal">true</span>;
        },

        _prepareModel: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
            
        </li>
        
        
        <li id="section-90">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-90">&#182;</a>
              </div>
              <p>set isSynced flag on each item model
before the the “add” event is triggered</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">var</span> model = BackboneBase.Collection.prototype._prepareModel.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
            <span class="hljs-keyword">if</span>(model &amp;&amp; <span class="hljs-keyword">this</span>.isSyncing) {
                model.isSynced = <span class="hljs-literal">true</span>;
            }
            <span class="hljs-keyword">return</span> model;
        },

        _afterSetBeforeTrigger: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">this</span>.isSynced = <span class="hljs-literal">true</span>;
            <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.isSyncing;

            <span class="hljs-keyword">var</span> triggerDeepSync = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                <span class="hljs-keyword">this</span>.trigger(<span class="hljs-string">"deepsync"</span>, <span class="hljs-keyword">this</span>);
            }.bind(<span class="hljs-keyword">this</span>);

            <span class="hljs-keyword">var</span> afterAllItemsDeepSync,
                itemsToSyncCount = <span class="hljs-number">0</span>,
                itemSyncedCb = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                    afterAllItemsDeepSync();
                };

            <span class="hljs-keyword">this</span>.each(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">item</span>) </span>{
                <span class="hljs-keyword">if</span>(item.isSyncing) {
                    itemsToSyncCount++;
                    item.once(<span class="hljs-string">"deepsync"</span>, itemSyncedCb);
                }
            }, <span class="hljs-keyword">this</span>);

            <span class="hljs-keyword">if</span>(itemsToSyncCount &gt; <span class="hljs-number">0</span>) {
                afterAllItemsDeepSync = _.after(itemsToSyncCount, triggerDeepSync);
            } <span class="hljs-keyword">else</span> {
                triggerDeepSync();
            }

        },

        _representsToMany: <span class="hljs-literal">true</span>

    });</pre></div></div>
            
        </li>
        
        
        <li id="section-91">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-91">&#182;</a>
              </div>
              <p>Resolve the model/collection class that is specified for a relation.
Supports lazy resolution when passing in a function.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">resolveRelClass</span>(<span class="hljs-params">cls</span>) </span>{
        <span class="hljs-keyword">if</span>(_.isFunction(cls)) {
            <span class="hljs-keyword">if</span>(cls.prototype._representsToOne || cls.prototype._representsToMany) {
                <span class="hljs-keyword">return</span> cls;
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">var</span> resolvedClass = cls();
                <span class="hljs-keyword">if</span>(!resolvedClass.prototype._representsToOne &amp;&amp; !resolvedClass.prototype._representsToMany) {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"The model class for the relation could not be resolved. "</span> +
                        <span class="hljs-string">"It must extend either Backbone.Model or Backbone.Collection and the "</span> +
                        <span class="hljs-string">"backbone-rel extension must be loaded"</span>);
                }
                <span class="hljs-keyword">return</span> resolvedClass;
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Cannot resolve relation class from "</span> + cls);
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">capitalize</span>(<span class="hljs-params">string</span>) </span>{
        <span class="hljs-keyword">return</span> string.charAt(<span class="hljs-number">0</span>).toUpperCase() + string.substring(<span class="hljs-number">1</span>);
    };</pre></div></div>
            
        </li>
        
        
        <li id="section-92">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-92">&#182;</a>
              </div>
              <p>Returns the ID reference attribute key for the given reference key
e.g.: “userId” for reference with key “user” with idAttribute “id”,
“typeKey” for a reference “type” to a model with idAttribute “key”,
“taskIds” for a reference “tasks” to a collection</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">refKeyToIdRefKey</span>(<span class="hljs-params">referencedModel, key</span>) </span>{
        <span class="hljs-keyword">var</span> idAttribute = referencedModel.prototype.idAttribute || <span class="hljs-string">"id"</span>;
        <span class="hljs-keyword">if</span>(referencedModel.prototype._representsToMany) {
            <span class="hljs-keyword">return</span> key.replace(<span class="hljs-regexp">/s{0,1}$/</span>, capitalize(idAttribute)+<span class="hljs-string">"s"</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> key + capitalize(idAttribute);
        }
    }</pre></div></div>
            
        </li>
        
        
        <li id="section-93">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-93">&#182;</a>
              </div>
              <p>Wraps the xhr success and error callbacks to hook in additional method invocation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">wrapOptionsCallbacks</span>(<span class="hljs-params">method, options</span>) </span>{
        options = options || {};
        <span class="hljs-keyword">var</span> success = options.success;
        <span class="hljs-keyword">var</span> error = options.error;
        options.success = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) </span>{
            method(options);
            <span class="hljs-keyword">if</span>(success) success(resp);
        };
        options.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) </span>{
            method(options);
            <span class="hljs-keyword">if</span>(error) error(resp);
        };
        <span class="hljs-keyword">return</span> options;
    }


    _.extend(exports, Backbone);
    <span class="hljs-keyword">return</span> Backbone;
}));</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>