PageRenderTime 11ms CodeModel.GetById 5ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/index.html

https://github.com/sventschui/Backbone-relational
HTML | 1663 lines | 1494 code | 158 blank | 11 comment | 0 complexity | 69ad0e913af9a87a436c298eca91ba96 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<!DOCTYPE HTML>
   2<html xmlns="http://www.w3.org/1999/html">
   3<head>
   4	<meta http-equiv="content-type" content="text/html;charset=UTF-8">
   5	<meta http-equiv="X-UA-Compatible" content="chrome=1">
   6	<meta name="viewport" content="width=device-width">
   7	<link rel="icon" href="static/images/favicon.ico">
   8	
   9	<link href="http://fonts.googleapis.com/css?family=Arimo" rel="stylesheet" type="text/css">
  10	<link rel="stylesheet" type="text/css" href="static/css/style.css">
  11	
  12	<title>Backbone-relational.js</title>
  13
  14	<!--[if lt IE 9]>
  15	<script>
  16		document.createElement('header');
  17		document.createElement('nav');
  18		document.createElement('section');
  19		document.createElement('article');
  20		document.createElement('aside');
  21		document.createElement('footer');
  22		document.createElement('hgroup');
  23	</script>
  24	<![endif]-->
  25</head>
  26<body>
  27<div id="sidebar">
  28	<a class="toc_title" href="#">
  29		Backbone-relational.js <span class="version">(0.8.8)</span>
  30	</a>
  31
  32	<ul>
  33		<li class="link_out"><a href="https://github.com/PaulUithol/Backbone-relational">GitHub Repository</a></li>
  34	</ul>
  35
  36	<a class="toc_title" href="#introduction">
  37		Introduction
  38	</a>
  39
  40	<a class="toc_title" href="#installation">
  41		Installation
  42	</a>
  43
  44	<a class="toc_title" href="#RelationalModel">
  45		Backbone.RelationalModel
  46	</a>
  47
  48	<ul>
  49		<li>
  50			<a href="#RelationalModel-relations">relations</a>
  51			<ul>
  52				<li><a href="#relations-key">key</a></li>
  53				<li><a href="#relations-relatedModel">relatedModel</a></li>
  54				<li><a href="#relations-type">type</a></li>
  55				<li><a href="#relations-includeInJSON">includeInJSON</a></li>
  56				<li><a href="#relations-autoFetch">autoFetch</a></li>
  57				<li><a href="#relations-collectionType">collectionType</a></li>
  58				<li><a href="#relations-collectionKey">collectionKey</a></li>
  59				<li><a href="#relations-collectionOptions">collectionOptions</a></li>
  60				<li><a href="#relations-createModels">createModels</a></li>
  61				<li><a href="#relations-keySource">keySource</a></li>
  62				<li><a href="#relations-keyDestination">keyDestination</a></li>
  63				<li><a href="#relations-parse">parse</a></li>
  64				<li><a href="#relations-reverseRelation">reverseRelation</a></li>
  65			</ul>
  66		</li>
  67	</ul>
  68	<ul>
  69		<li><a href="#RelationalModel-subModelTypes">subModelTypes</a></li>
  70		<li><a href="#RelationalModel-subModelTypeAttribute">subModelTypeAttribute</a></li>
  71	</ul>
  72	<ul>
  73		<li><a href="#RelationalModel-getAsync">getAsync</a></li>
  74		<li><a href="#RelationalModel-getIdsToFetch">getIdsToFetch</a></li>
  75		<li><a href="#RelationalModel-getRelation">getRelation</a></li>
  76		<li><a href="#RelationalModel-getRelations">getRelations</a></li>
  77		<li><a href="#RelationalModel-set">set</a></li>
  78		<li><a href="#RelationalModel-toJSON">toJSON</a></li>
  79	</ul>
  80	<ul>
  81		<li><a href="#RelationalModel-setup">setup</a></li>
  82		<li><a href="#RelationalModel-build">build</a></li>
  83		<li><a href="#RelationalModel-findOrCreate">findOrCreate</a></li>
  84		<li><a href="#RelationalModel-find">find</a></li>
  85		<li><a href="#RelationalModel-findModel">findModel</a></li>
  86	</ul>
  87	<ul>
  88		<li><a href="#RelationalModel-events"><strong>Catalog of Events</strong></a></li>
  89	</ul>
  90
  91	<a class="toc_title" href="#Relation">
  92		Backbone.Relation
  93	</a>
  94
  95	<ul>
  96		<li><a href="#Relation-HasOne">HasOne</a></li>
  97		<li><a href="#Relation-HasMany">HasMany</a></li>
  98	</ul>
  99
 100	<a class="toc_title" href="#Store">
 101		Backbone.Store
 102	</a>
 103
 104	<ul>
 105		<li><a href="#Store-addModelScope">addModelScope</a></li>
 106		<li><a href="#Store-removeModelScope">removeModelScope</a></li>
 107		<li><a href="#Store-reset">reset</a></li>
 108	</ul>
 109
 110	<a class="toc_title" href="#examples">
 111		Examples
 112	</a>
 113
 114	<a class="toc_title" href="#change-log">
 115		Change Log
 116	</a>
 117
 118	<a class="toc_title" href="#under-the-hood">
 119		Under the Hood
 120	</a>
 121</div>
 122
 123<div class="container">
 124	<section>
 125		<h1>
 126			Backbone-relational.js
 127		</h1>
 128
 129		<p>
 130			When developing any medium to large-scale web application, you often get to the point where
 131			an action by a user can cause a number of different models to change on the client and the server.
 132		</p>
 133		<p>
 134			You can try to keep updating both sides of a relation manually for every action, and individually call
 135			<q><a href="http://backbonejs.org/#Model-save">save</a></q> or <q><a href="http://backbonejs.org/#Model-fetch">fetch</a></q>
 136			on each of the changed models to sync with the server, but that quickly turns into a tedious process and
 137			results in multiple requests.
 138		</p>
 139		<p>
 140			Using Backbone-relational, we can configure relationships between our models, and sync the model and all of its related models with a single
 141			call to <q><a href="http://backbonejs.org/#Model-save">save</a></q>, <q><a href="#RelationalModel-getAsync">getAsync</a></q> or <q><a href="http://backbonejs.org/#Model-fetch">fetch()</a></q>
 142			after setting up a model's <q><a href="#RelationalModel-relations">relations</a></q>.
 143		</p>
 144		<p>
 145			Backbone-relational is hosted on <a href="https://github.com/PaulUithol/Backbone-relational">GitHub</a>,
 146			and is available under the <a href="https://github.com/PaulUithol/Backbone-relational/blob/master/LICENSE.txt">MIT license</a>.
 147		</p>
 148		<p>
 149			Thanks to <a href="http://progressiveplanning.com">Progressive Planning</a> for allowing me the time to
 150			work on Backbone-relational!
 151		</p>
 152	</section>
 153
 154	<section id="downloads">
 155		<h2>
 156			Downloads &amp; Dependencies
 157			<span style="padding-left: 7px; font-size:11px; font-weight: normal;" class="interface">
 158				(Right-click, and use "Save As")
 159			</span>
 160		</h2>
 161
 162		<table>
 163			<tr>
 164				<td><a class="punch" href="https://raw.github.com/PaulUithol/Backbone-relational/0.8.8/backbone-relational.js">Latest Release (0.8.8)</a></td>
 165				<td class="text"><i>~70kb. Full source, uncompressed, lots of comments.</i></td>
 166			</tr>
 167			<tr>
 168				<td><a class="punch" href="https://raw.github.com/PaulUithol/Backbone-relational/master/backbone-relational.js">Development Version</a></td>
 169			</tr>
 170		</table>
 171
 172		<p>
 173			Backbone-relational depends on <a href="http://backbonejs.org/">Backbone.js</a> <small>(>= 1.0.0)</small>,
 174			which itself requires <a href="http://underscorejs.org">Underscore.js</a> <small>(> 1.4.4)</small> and
 175			<a href="http://jquery.com">jQuery</a> <small>(> 1.7.0)</small> or
 176			<a href="http://zeptojs.com/">Zepto</a>.
 177		</p>
 178	</section>
 179
 180	<section id="introduction">
 181		<h2>Introduction</h2>
 182
 183		<p>
 184			Backbone-relational.js provides one-to-one, one-to-many and many-to-one relations
 185			between models for Backbone. To use relations, extend <a href="#RelationalModel"><strong>Backbone.RelationalModel</strong></a>
 186			(instead of a regular <a href="http://backbonejs.org/#Model">Backbone.Model</a>) and define a
 187			<a href="#RelationalModel-relations"><q>relations</q></a> property, containing an array of option objects.
 188			Each relation must define (at least) the <a href="#relations-type"><q>type</q></a>, <a href="#relations-key"><q>key</q></a>,
 189			and <a href="#relations-relatedModel"><q>relatedModel</q></a>. Available relation types are
 190			<a href="#Relation-HasOne"><q>Backbone.HasOne</q></a> and <a href="#Relation-HasMany"><q>Backbone.HasMany</q></a>.
 191		</p>
 192
 193		<p>
 194			Backbone-relational's main features include:
 195		</p>
 196
 197		<ul>
 198			<li>
 199				Bidirectional relations, which notify related models of changes through events.
 200			</li>
 201			<li>
 202				Control how relations are serialized using the <a href="#relations-includeInJSON"><q>includeInJSON</q></a> option.
 203			</li>
 204			<li>
 205				Automatically convert nested objects in a model's attributes into model instances (using the
 206				<a href="#relations-createModels"><q>createModels</q></a> option, which is <q>true</q> by default).
 207			</li>
 208			<li>
 209				Lazily retrieve a set of related models through the <a href="#RelationalModel-getAsync"><q>getAsync</q></a>
 210				method.
 211			</li>
 212			<li>
 213				Determine the type of HasMany collections with <a href="#relations-collectionType"><q>collectionType</q></a>.
 214			</li>
 215		</ul>
 216
 217		<p>
 218			You can also bind new events to a <strong>Backbone.RelationalModel</strong> for an:
 219		</p>
 220
 221		<ul>
 222			<li>
 223				<strong>addition</strong> to a HasMany relation with <a href="#RelationalModel-events">add:&lt;key&gt;</a>.
 224			</li>
 225			<li>
 226				<strong>removal</strong> from a HasMany relation with <a href="#RelationalModel-events">remove:&lt;key&gt;</a>.
 227			</li>
 228			<li>
 229				<strong>reset</strong> of a HasMany relation with <a href="#RelationalModel-events">reset:&lt;key&gt;</a>.
 230			</li>
 231			<li>
 232				<strong>changes</strong> to the contents of a HasMany or HasOne relations with <a href="#RelationalModel-events">change:
 233				&lt;key&gt;</a>.
 234			</li>
 235		</ul>
 236	</section>
 237
 238	<section id="installation">
 239		<h2>Installation</h2>
 240
 241		<p>
 242			Backbone-relational depends on <a href="http://backbonejs.org/">Backbone.js</a> (and thus on
 243			<a href="http://underscorejs.org">Underscore.js</a>). Include Backbone-relational right after Backbone
 244			and Underscore:
 245		</p>
 246
 247<pre class="language-markup"><code class="language-markup"><!--
 248-->&lt;script type="text/javascript" src="./js/underscore.js"&gt;&lt;/script&gt;
 249<!-- -->&lt;script type="text/javascript" src="./js/backbone.js"&gt;&lt;/script&gt;
 250<!-- -->&lt;script type="text/javascript" src="./js/backbone-relational.js"&gt;&lt;/script&gt;
 251</code></pre>
 252
 253		<p class="notice">
 254			Note for <strong>CoffeeScript</strong> users: due to the way the <q>extends</q> keyword is implemented in
 255			CoffeeScript, you may have to make an extra call to <a href="#RelationalModel-setup"><q>setup</q></a> for
 256			your models. See the <a href="#RelationalModel-setup"><q>setup</q></a> documentation for details.
 257		</p>
 258	</section>
 259
 260	<section id="RelationalModel">
 261		<h2>
 262			Backbone.RelationalModel
 263		</h2>
 264
 265		<p>
 266			When using Backbone-relational, each model defining (or receiving) <q>relations</q> must extend
 267			<strong>Backbone.RelationalModel</strong> in order to function. <strong>Backbone.RelationalModel</strong>
 268			introduces a couple of new methods, events and properties. It's important to know which are properties,
 269			which are methods of an	instance, and which operate on the type itself.
 270			These three subcategories are detailed below.
 271		</p>
 272
 273		<p>
 274			<strong>Properties</strong> can be defined when extending Backbone.RelationalModel, or a subclass thereof.
 275		</p>
 276
 277		<ul class="small">
 278			<li><a href="#RelationalModel-relations">relations</a></li>
 279			<li><a href="#RelationalModel-subModelTypes">subModelTypes</a></li>
 280			<li><a href="#RelationalModel-subModelTypeAttribute">subModelTypeAttribute</a></li>
 281		</ul>
 282
 283		<p>
 284			<strong>Instance methods</strong> operate on an instance of a type.
 285		</p>
 286
 287		<ul class="small">
 288			<li><a href="#RelationalModel-getAsync">getAsync</a></li>
 289			<li><a href="#RelationalModel-getIdsToFetch">getIdsToFetch</a></li>
 290			<li><a href="#RelationalModel-getRelation">getRelation</a></li>
 291			<li><a href="#RelationalModel-getRelations">getRelations</a></li>
 292			<li><a href="#RelationalModel-set">set</a></li>
 293			<li><a href="#RelationalModel-toJSON">toJSON</a></li>
 294		</ul>
 295
 296		<p>
 297			<strong>Static methods</strong> operate on the type itself, as opposed to operating on model instances.
 298		</p>
 299
 300		<ul class="small">
 301			<li><a href="#RelationalModel-setup">setup</a></li>
 302			<li><a href="#RelationalModel-build">build</a></li>
 303			<li><a href="#RelationalModel-findOrCreate">findOrCreate</a></li>
 304			<li><a href="#RelationalModel-find">find</a></li>
 305			<li><a href="#RelationalModel-findModel">findModel</a></li>
 306		</ul>
 307
 308		<h3 id="RelationalModel-properties">
 309			Properties
 310		</h3>
 311
 312		<h4 class="code" id="RelationalModel-relations">
 313			relations<code>relation[]</code>
 314		</h4>
 315		<p>
 316			A <strong>Backbone.RelationalModel</strong> may contain an array of relation definitions. Each relation supports a number of
 317			options, of which <a href="#relations-relatedModel"><q>relatedModel</q></a>, <a href="#relations-key"><q>key</q></a> and
 318			<a href="#relations-type"><q>type</q></a> are mandatory. A relation could look like the following:
 319		</p>
 320
 321<pre class="language-javascript"><code id="example-zoo" class="language-javascript runnable"><!--
 322-->Zoo = Backbone.RelationalModel.extend({
 323	relations: [{
 324		type: Backbone.HasMany,
 325		key: 'animals',
 326		relatedModel: 'Animal',
 327		collectionType: 'AnimalCollection',
 328		reverseRelation: {
 329			key: 'livesIn',
 330			includeInJSON: 'id'
 331			// 'relatedModel' is automatically set to 'Zoo'; the 'relationType' to 'HasOne'.
 332		}
 333	}]
 334});
 335
 336Animal = Backbone.RelationalModel.extend({
 337	urlRoot: '/animal/'
 338});
 339
 340AnimalCollection = Backbone.Collection.extend({
 341	model: Animal
 342});
 343
 344// We've now created a fully managed relation. When you add or remove model from `zoo.animals`,
 345// or update `animal.livesIn`, the other side of the relation will automatically be updated.
 346var artis = new Zoo( { name: 'Artis' } );
 347var lion = new Animal( { species: 'Lion', livesIn: artis } );
 348
 349// `animals` in `artis` now contains `lion`
 350alert( artis.get( 'animals' ).pluck( 'species' ) );
 351</code></pre>
 352<pre class="language-javascript nomargin"><code class="language-javascript runnable" data-setup="#example-zoo"><!--
 353-->var amersfoort = new Zoo( { name: 'Dierenpark Amersfoort', animals: [ lion ] } );
 354
 355// `lion` now livesIn `amersfoort`, and `animals` in `artis` no longer contains `lion`
 356alert( lion.get( 'livesIn' ).get( 'name' ) + ', ' + artis.get( 'animals' ).length );
 357</code></pre>
 358
 359		<section id="relations-key">
 360			<h4 class="code">
 361				key<code>relation.key</code>
 362			</h4>
 363			<p>
 364				Required. A string that references an attribute name on <a href="#relations-relatedModel"><q>relatedModel</q></a>.
 365			</p>
 366
 367			<h4 class="code" id="relations-relatedModel">
 368				relatedModel<code>relation.relatedModel</code>
 369			</h4>
 370			<p>
 371				Required. A string that can be resolved to an object on the global scope, or a reference to a
 372				<strong>Backbone.RelationalModel</strong>. Also see <a href="#Store-addModelScope"><q>addModelScope</q></a>.
 373			</p>
 374		</section>
 375
 376		<section id="relations-type">
 377			<h4 class="code">
 378				type<code>relation.type</code>
 379			</h4>
 380			<p>
 381				Required. A string that references a <a href="#Relation"><q>Backbone.Relation</q></a> type by name ("HasOne" or "HasMany"),
 382				or a direct reference to a relation type.
 383			</p>
 384			<p>
 385				You can model a one-to-one or a many-to-one relationship by declaring <q>type</q> as the string "HasOne", or by
 386				directly referencing <a href="#Relation-HasOne"><q>Backbone.HasOne</q></a>. A HasOne relation contains a single
 387				<strong>Backbone.RelationalModel</strong>. The default <q>reverseRelation.type</q> for a "HasOne" relation is
 388				"HasMany". This can be set to "HasOne" instead, to create a one-to-one relation.
 389			</p>
 390			<p>
 391				You can model a one-to-many relationship by declaring <q>type</q> as the string "HasMany", or by directly
 392				referencing <a href="#Relation-HasMany"><q>Backbone.HasMany</q></a>. A HasMany relation contains a Backbone.Collection,
 393				containing zero or more	<strong>Backbone.RelationalModel</strong>s. The default <q>reverseRelation.type</q>
 394				for a HasMany relation is HasOne; this is the only option here, since many-to-many is not supported directly.
 395			</p>
 396			<p>
 397				It is possible model a many-to-many relationship using two <a href="#Relation-HasMany"><q>Backbone.HasMany</q></a>
 398				relations, with a link model in between:
 399			</p>
 400		</section>
 401
 402<pre class="language-javascript"><code class="language-javascript" id="example-job"><!--
 403-->Person = Backbone.RelationalModel.extend({
 404	relations: [{
 405		type: 'HasMany',
 406		key: 'jobs',
 407		relatedModel: 'Job',
 408		reverseRelation: {
 409			key: 'person'
 410		}
 411	}]
 412});
 413
 414// A link object between 'Person' and 'Company'
 415Job = Backbone.RelationalModel.extend({
 416	defaults: {
 417		'startDate': null,
 418		'endDate': null
 419	}
 420})
 421
 422Company = Backbone.RelationalModel.extend({
 423	relations: [{
 424		type: 'HasMany',
 425		key: 'employees',
 426		relatedModel: 'Job',
 427		reverseRelation: {
 428			key: 'company'
 429		}
 430	}]
 431});
 432</code></pre>
 433
 434		<section id="relations-includeInJSON">
 435			<h4 class="code">
 436				includeInJSON<code>relation.includeInJSON</code>
 437			</h4>
 438			<p>
 439				A boolean, a string referencing one of the model's attributes, or an array of strings referencing model
 440				attributes. Default: <q>true</q>.
 441			</p>
 442			<p>
 443				Determines how the contents of a relation will be serialized following a call to the
 444				<a href="#RelationalModel-toJSON"><q>toJSON</q></a> method. If you specify a:
 445			</p>
 446
 447			<ul>
 448				<li>
 449					<strong>Boolean</strong>: a value of true serializes the full set of attributes on the related model(s).
 450					Set to false to	exclude the relation completely.
 451				</li>
 452				<li>
 453					<strong>String</strong>: include a single attribute from the related model(s). For example, 'name', or
 454					<q>Backbone.Model.prototype.idAttribute</q> to include ids.
 455				</li>
 456				<li>
 457					<strong>String[]</strong>: includes the specified attributes from the related model(s).
 458				</li>
 459			</ul>
 460
 461			<p>
 462				Specifying <q>true</q> will cascade, meaning the relations of nested model will get serialized as well,
 463				until either a different value is found for <q>includeInJSON</q> or we encounter a model that has already
 464				been serialized.
 465			</p>
 466		</section>
 467
 468		<section id="relations-autoFetch">
 469			<h4 class="code">
 470				autoFetch<code>relation.autoFetch</code>
 471			</h4>
 472			<p>
 473				A boolean or an object. Default: <q>false</q>.
 474			</p>
 475			<p>
 476				If this property is set to <q>true</q>, when a model is instantiated the related model is
 477				automatically fetched using <a href="#RelationalModel-getAsync"><q>getAsync</q></a>. The
 478				value of the property can also be an object. In that case the object is passed to
 479				<a href="#RelationalModel-getAsync"><q>getAsync</q></a> as the options parameter.
 480			</p>
 481			<p>
 482				Note that <q>autoFetch</q> operates independently from other `fetch` operations,
 483				including those that may have fetched the current model.
 484			</p>
 485		</section>
 486
 487<pre class="language-javascript"><code class="language-javascript"><!--
 488-->var Shop = Backbone.RelationalModel.extend({
 489	relations: [
 490		{
 491			type: Backbone.HasMany,
 492			key: 'customers',
 493			relatedModel: 'Customer',
 494			autoFetch: true
 495		},
 496		{
 497			type: Backbone.HasOne,
 498			key: 'address',
 499			relatedModel: 'Address',
 500			autoFetch: {
 501				success: function( model, response ) {
 502					//...
 503				},
 504				error: function( model, response ) {
 505					//...
 506				}
 507			}
 508		}
 509	]
 510});
 511</code></pre>
 512
 513		<section id="relations-collectionType">
 514			<h4 class="code">
 515				collectionType<code>relation.collectionType</code>
 516			</h4>
 517			<p>
 518				A string that can be resolved to an object type on the global scope, or a reference to a
 519				<strong>Backbone.Collection</strong> type.
 520			</p>
 521			<p>
 522				Determine the type of collections used for a HasMany relation. If you define a
 523				url(models&lt;Backbone.Model[]&gt;) function on the specified collection, this enables
 524				<a href="#RelationalModel-getAsync"><q>getAsync</q></a> to fetch all missing models in one request,
 525				instead of firing a separate request for each.
 526			</p>
 527
 528			<h4 class="code" id="relations-collectionKey">
 529				collectionKey<code>relation.collectionKey</code>
 530			</h4>
 531			<p>
 532				A string or a boolean. Default: <q>true</q>.
 533			</p>
 534			<p>
 535				Used to create a back reference from the <strong>Backbone.Collection</strong> used for a HasMany relation to the model on
 536				the other side of this relation. By default, the relation's key attribute will be used to create a reference to
 537				the RelationalModel instance from the generated collection. If you set <q>collectionKey</q> to a string,
 538				it will use that string as the reference to the RelationalModel, rather than the
 539				relation's key attribute. If you don't want this behavior at all, set <q>collectionKey</q> to <q>false</q>
 540				(or any falsy value) and this reference will not be created.
 541			</p>
 542		</section>
 543
 544		<section id="relations-collectionOptions">
 545			<h4 class="code">
 546				collectionOptions<code>relation.collectionOptions</code>
 547			</h4>
 548			<p>
 549				An options hash, or a function that accepts an instance of a <strong>Backbone.RelationalModel</strong> and returns an options
 550				hash.
 551			</p>
 552			<p>
 553				Used to provide options for the initialization of the collection in the 'Many'-end of a HasMany relation. Can be
 554				an options hash or a function that should take the instance in the 'One'-end of the 'HasMany' relation and return
 555				an options hash.
 556			</p>
 557		</section>
 558
 559		<section id="relations-createModels">
 560			<h4 class="code">
 561				createModels<code>relation.createModels</code>
 562			</h4>
 563			<p>
 564				A boolean. Default: <q>true</q>.
 565			</p>
 566			<p>
 567				Specifies whether models will be created from nested objects or not.
 568			</p>
 569		</section>
 570
 571		<section id="relations-keySource">
 572			<h4 class="code">
 573				keySource<code>relation.keySource</code>
 574			</h4>
 575			<p>
 576				A string that references an attribute to deserialize data for <a href="#relations-relatedModel"><q>relatedModel</q></a> from.
 577			</p>
 578			<p>
 579				Used to override key when determining what data to use when (de)serializing a relation, since the data backing
 580				your relations may use different naming conventions. For example, a Rails backend may provide the keys suffixed
 581				with <q>_id</q> or <q>_ids</q>. The behavior for <q>keySource</q> corresponds to the following rules:
 582			</p>
 583			<p>
 584				When a relation is instantiated, the contents of the <q>keySource</q> are used as its initial data. The
 585				application uses the regular key attribute to interface with the relation and the models in it; the
 586				<q>keySource</q> is not available as an attribute for the model. So you	may be provided with data containing
 587				<q>animal_ids</q>, while you want to access this relation as <q>zoo.get('animals')</q>.
 588			</p>
 589			<p class="warning">
 590				Note that setting <q>keySource</q> will set <a href="#relations-keyDestination"><q>keyDestination</q></a>
 591				to the same value, if it isn't specified itself.
 592				This means that when saving zoo, the animals attribute will be serialized back into the <q>animal_ids</q> key.
 593			</p>
 594			<p class="warning">
 595				WARNING: when using a keySource, you should not use that attribute name for	other purposes.
 596			</p>
 597		</section>
 598
 599		<section id="relations-keyDestination">
 600			<h4 class="code">
 601				keyDestination<code>relation.keyDestination</code>
 602			</h4>
 603			<p>
 604				A string that references an attribute to serialize <a href="#relations-relatedModel"><q>relatedModel</q></a> into.
 605			</p>
 606			<p>
 607				Used to override key (and <a href="#relations-keySource"><q>keySource</q></a>) when determining what attribute to be
 608				written into when serializing a relation, since the server backing your relations may use different naming
 609				conventions. For example, a Rails backend may expect the keys to be suffixed with _attributes for nested
 610				attributes.
 611			</p>
 612			<p>
 613				When calling <a href="#RelationalModel-toJSON"><q>toJSON</q></a> on a model (either via
 614				<strong>Backbone.Sync</strong>, or directly), the data in the key attribute is transformed and assigned to the
 615				<q>keyDestination</q>.
 616			</p>
 617			<p>
 618				So you may want a relation to be serialized into the animals_attributes key, while you want to access this
 619				relation as <q>zoo.get( 'animals' );</q>.
 620			</p>
 621			<p class="warning">
 622				WARNING: when using a <q>keyDestination</q>, you should not use that attribute name for other purposes.
 623			</p>
 624		</section>
 625
 626<pre class="language-javascript"><code class="language-javascript runnable" data-setup="#example-zoo"><!--
 627-->var FarmAnimal = Animal.extend();
 628
 629// This `Farm` is confused, like legacy stuff can be. It wants its data back on a completely
 630// different key than it supplies it on. We want to use a different one in our app as well.
 631var Farm = Backbone.RelationalModel.extend({
 632	relations: [{
 633		type: Backbone.HasMany,
 634		key: 'animals',
 635		keySource: 'livestock',
 636		keyDestination: 'pets',
 637		relatedModel: FarmAnimal,
 638		reverseRelation: {
 639			key: 'farm',
 640			includeInJSON: 'name'
 641		}
 642	}]
 643});
 644
 645// Create a `Farm`; parse `species`, add to `animals`, output goes to `pets`.
 646var farm = new Farm( { name: 'Old MacDonald', livestock: [ { species: 'Sheep' } ] } );
 647farm.get( 'animals' ).add( { species: 'Cow' } );
 648alert( JSON.stringify( farm.toJSON(), null, 4 ) );
 649</code></pre>
 650
 651		<section id="relations-parse">
 652			<h4 class="code">
 653				parse<code>relation.parse</code>
 654			</h4>
 655			<p>
 656				A boolean. Default: <q>false</q>.
 657			</p>
 658			<p>
 659				If you have a relation where the models should be parsed when data is being set, specify `parse: true`.
 660			</p>
 661		</section>
 662
 663		<section id="relations-reverseRelation">
 664			<h4 class="code">
 665				reverseRelation<code>relation.reverseRelation</code>
 666			</h4>
 667			<p>
 668				An object specifying the relation pointing back to this model from <a href="#relations-relatedModel"><q>relatedModel</q></a>.
 669			</p>
 670			<p>
 671				If the relation should be bidirectional, specify the details for the reverse relation here. It's only mandatory
 672				to supply a <a href="#relations-key"><q>key</q></a>; <a href="#relations-relatedModel"><q>relatedModel</q></a> is automatically
 673				set. The default type for a <q>reverseRelation</q> is HasMany for a
 674				HasOne relation (which can be overridden to HasOne in order to create a one-to-one relation), and HasOne for a
 675				HasMany relation. In this case, you cannot create a <q>reverseRelation</q> with
 676				type HasMany as well; please see Many-to-many relations on how to model these type of relations.
 677			</p>
 678			<p class="warning">
 679				Note that if you define a relation (plus a reverseRelation) on a model,	but don't actually create an instance
 680				of that model, it is possible <q>initializeRelations</q> will never get	called, and the reverseRelation
 681				will not be initialized. This can happen when <q>extend</q> has been overridden, or redefined as in CoffeeScript.
 682				See <a href="#RelationalModel-setup">setup</a>.
 683			</p>
 684		</section>
 685
 686		<section id="RelationalModel-subModelTypes">
 687			<h4 class="code">
 688				subModelTypes<code>relationalModel.subModelTypes(attributes&lt;object&gt;, [options&lt;object&gt;])</code>
 689			</h4>
 690			<p>
 691				An object. Default: <q>{}</q>.
 692			</p>
 693			<p>
 694				A mapping that defines what submodels exist for the model (the superModel) on which
 695				<q>subModelTypes</q> is defined. The keys are used to match the
 696				<a href="#RelationalModel-subModelTypeAttribute"><q>subModelTypeAttribute</q></a> when deserializing, and the values
 697				determine what type of submodel should be created for a key. When building model instances from data, we need to
 698				determine what kind of object we're dealing with in order to create instances of the right subModel type. This
 699				is done by finding the model for which the key is equal to the value of the
 700				<a href="#RelationalModel-subModelTypeAttribute"><q>subModelTypeAttribute</q></a> attribute on the passed in data.
 701			</p>
 702			<p>
 703				Each subModel is considered to be a proper submodel of its superclass (the model type you're extending), with a
 704				shared id pool. This means that when looking for an object of the supermodel's type, objects of a submodel's type
 705				can be returned as well, as long as the id matches. In effect, any relations pointing to the supermodel will look
 706				for instances of its submodels as well.
 707			</p>
 708
 709
 710<pre class="language-javascript"><code class="language-javascript runnable" data-setup="#example-zoo"><!--
 711-->Mammal = Animal.extend({
 712	subModelTypes: {
 713		'primate': 'Primate',
 714		'carnivore': 'Carnivore'
 715	}
 716});
 717
 718Primate = Mammal.extend();
 719Carnivore = Mammal.extend();
 720
 721MammalCollection = AnimalCollection.extend({
 722	model: Mammal
 723});
 724
 725// Create a collection that contains a 'Primate' and a 'Carnivore'.
 726var mammals = new MammalCollection([
 727	{ id: 3, species: 'chimp', type: 'primate' },
 728	{ id: 5, species: 'panther', type: 'carnivore' }
 729]);
 730
 731var chimp = mammals.get( 3 );
 732
 733alert( 'chimp is an animal? ' + ( chimp instanceof Animal ) + '\n' +
 734	'chimp is a carnivore? ' + ( chimp instanceof Carnivore ) + '\n' +
 735	'chimp is a primate? ' + ( chimp instanceof Primate ) );
 736</code></pre>
 737
 738			<p>
 739				Suppose that we have an Mammal model and a Primate model extending Mammal. If we have a Primate object with id 3,
 740				this object will be returned when we have a relation pointing to a Mammal with id 3, as Primate is regarded a
 741				specific kind of Mammal; it's just a Mammal with possibly some primate-specific properties or methods.
 742			</p>
 743			<p class="warning">
 744				Note that this means that there cannot be any overlap in ids between instances of Mammal and Primate, as the
 745				Primate with id 3 will be the Mammal with id 3.
 746			</p>
 747		</section>
 748
 749		<section id="RelationalModel-subModelTypeAttribute">
 750			<h4 class="code">
 751			subModelTypeAttribute<code>relationalModel.subModelTypeAttribute</code>
 752		</h4>
 753			<p>
 754				A string. Default: <q>type</q>.
 755			</p>
 756			<p>
 757				The <q>subModelTypeAttribute</q> is a references an attribute on the data
 758				used to instantiate <a href="#relations-relatedModel"><q>relatedModel</q></a>. The attribute that will be checked to
 759				determine the type of model that should be built when a raw object of attributes is set as the related value,
 760				and if the <a href="#relations-relatedModel"><q>relatedModel</q></a> has one or more submodels.
 761			</p>
 762		</section>
 763
 764		<h3 id="RelationalModel-instance-methods">
 765			Instance methods
 766		</h3>
 767
 768		<section id="RelationalModel-getAsync">
 769			<h4 class="code">
 770				getAsync<code>relationalModel.getAsync(attr&lt;string&gt;, [options&lt;object&gt;], [refresh&lt;boolean&gt;])</code>
 771			</h4>
 772			<p>
 773				Returns: <q>jQuery.Deferred</q> A <a href="http://api.jquery.com/category/deferred-object/">jQuery promise</a>
 774			</p>
 775			<p>
 776				Get an attribute's value asynchronously. If available, the local value will be returned.
 777				If <q>attr</q> is a relation and one or more of its models are not available, they will be fetched.
 778			</p>
 779			<p>
 780				This can be used specifically for lazy-loading scenarios.
 781				Only models are referenced in the attributes but have not been found/created yet are fetched.
 782				Setting <q>options.refresh</q> to true will fetch all model(s) from the server.
 783				In that case, any model that already exists will be updated with the retrieved data.
 784				The <q>options</q> object specifies options to be passed to <a href="http://backbonejs.org/#Sync">Backbone.Sync</a>.
 785			</p>
 786			<p>
 787				By default, a separate request will be fired for each model that is to be fetched from the server (if `key` references a collection).
 788				However, if your server/API supports it, you can fetch the set of models in one request by specifying a
 789				collectionType for the relation you call getAsync on. The <a href="#relations-collectionType"><q>collectionType</q></a>
 790				should have an overridden <a href="http://backbonejs.org/#Collection-url"><q>url</q></a>
 791				method that allows it to construct a url for an array of models. See <a href="#example-person">this example</a>
 792				or <a href="https://github.com/PaulUithol/backbone-tastypie">Backbone-tastypie</a> for an example.
 793			</p>
 794		</section>
 795
 796		<section id="RelationalModel-getIdsToFetch">
 797			<h4 class="code">
 798				getRelations<code>relationModel.getIdsToFetch(attr&lt;string|Backbone.Relation&gt;, )</code>
 799			</h4>
 800			<p>
 801				Returns: <q>Array</q> A list of the ids that will be fetched when calling <q>getAsync</q>.
 802			</p>
 803		</section>
 804
 805		<section id="RelationalModel-getRelation">
 806			<h4 class="code">
 807				getRelation<code>relationModel.getRelation(attr&lt;string&gt;)</code>
 808			</h4>
 809			<p>
 810				Returns: <q>Backbone.Relation</q> A single initialized relation on the model.
 811			</p>
 812		</section>
 813
 814		<section id="RelationalModel-getRelations">
 815			<h4 class="code">
 816				getRelations<code>relationModel.getRelations()</code>
 817			</h4>
 818			<p>
 819				Returns: <q>Backbone.Relation[]</q> The set of initialized relations on the model.
 820			</p>
 821		</section>
 822
 823		<section id="RelationalModel-set">
 824			<h4 class="code">
 825				set<code>set(key&lt;string&gt;, value, [options&lt;object&gt;]) <strong>or</strong> set(attributes&lt;object&gt;, [options&lt;object&gt;])</code>
 826			</h4>
 827			<p>
 828				Returns: <q>Backbone.RelationalModel</q> The model instance.
 829			</p>
 830			<p>
 831				The <q>set</q> method is overridden so that setting a value on an "relational" attribute will update that relation.
 832				This is especially important to keep in mind for <q>HasMany</q> relations (which are backed by a <q>Backbone.Collection</q>).
 833				For these, calling <q>set</q> can be thought of as being equivalent to calling <q>update</q> on the collection itself,
 834				including how the options are handled.
 835			</p>
 836			<p>
 837				Additional <q>options</q> for a <q>HasMany</q> relation:
 838			</p>
 839			<dl>
 840				<dt><q>add</q></dt>
 841				<dd>Default: <q>true</q>. If true, models specified in the arguments but not yet present in the relation will be added to the relation.</dd>
 842				<dt><q>merge</q></dt>
 843				<dd>Default: <q>true</q>. If true, existing models will be updated with the given attributes.</dd>
 844				<dt><q>remove</q></dt>
 845				<dd>Default: <q>true</q>. If true, models present in the relation but not specified in the arguments will be removed.</dd>
 846			</dl>
 847		</section>
 848
 849		<section id="RelationalModel-toJSON">
 850			<h4 class="code">
 851				toJSON<code>relationModel.toJSON(name&lt;string&gt;)</code>
 852			</h4>
 853			<p>
 854				Returns: <q>Object</q> The JSON representation of the model.
 855				See <a href="http://backbonejs.org/#Model-toJSON">Backbone.Model.toJSON</a>.
 856			</p>
 857			<p>
 858				The regular <q>toJSON</q> function has been overridden and modified to serialize (nested) relations
 859				according to their <a href="#relations-includeInJSON"><q>includeInJSON</q></a>, <a href="#relations-keySource"><q>keySource</q></a>,
 860				and <a href="#relations-keyDestination"><q>keyDestination</q></a> options.
 861			</p>
 862		</section>
 863
 864		<h3 id="RelationalModel-static-methods">
 865			Static methods
 866		</h3>
 867
 868		<section id="RelationalModel-setup">
 869			<h4 class="code">
 870				setup<code>relationModel.setup()</code>
 871			</h4>
 872			<p>
 873				Returns: <q>Backbone.RelationalModel.constuctor</q> The type.
 874			</p>
 875			<p>
 876				Initialize the relations and submodels for the model type. Normally, this happens automatically, but it doesn't if
 877				you're using CoffeeScript and using the syntax <q>class MyModel extends Backbone.RelationalModel</q> instead of
 878				the JavaScript equivalent of <q>MyModel = Backbone.RelationalModel.extend()</q>.
 879			</p>
 880			<p>
 881				This has advantages in CoffeeScript, but it also means that <q>Backbone.Model.extend</q> will not get called.
 882				Instead, CoffeeScript generates piece of code that would normally achieve the same.	However, <q>extend</q> is also
 883				the method that Backbone-relational overrides to set up relations as you're defining your <q>Backbone.RelationalModel</q> subclass.
 884			</p>
 885			<p>
 886				In this case, you should call <q>setup</q> manually after defining your subclass CoffeeScript-style. For example:
 887			</p>
 888			<p class="warning">
 889				Note: this is a static method. It operates on the model type itself, not on an instance of it.
 890			</p>
 891		</section>
 892
 893<pre class="language-javascript"><code class="language-javascript"><!--
 894-->class Animal extends Backbone.RelationalModel
 895    urlRoot: "/animal"
 896
 897class Mammal extends Animal
 898    subModelTypes:
 899        "primate": "Primate"
 900        "carnivore": "Carnivore"
 901
 902    relations: [
 903        # More relations
 904    ]
 905
 906Mammal.setup()
 907
 908class Primate extends Mammal
 909
 910class Carnivore extends Mammal
 911
 912chimp = Mammal.build( { id: 3, species: "chimp", type: "primate" } )
 913</code></pre>
 914
 915		<section id="RelationalModel-build">
 916			<h4 class="code">
 917				build<code>relationalModel.build(attributes&lt;object&gt;, [options&lt;object&gt;])</code>
 918			</h4>
 919			<p>
 920				Returns: <q>Backbone.RelationalModel</q> A model instance.
 921			</p>
 922			<p>
 923				Create an instance of a model, taking into account what submodels have been defined.
 924			</p>
 925			<p class="warning">
 926				Note: this is a static method. It operates on the model type itself, not on an instance.
 927			</p>
 928		</section>
 929
 930		<section id="RelationalModel-findOrCreate">
 931			<h4 class="code">
 932				findOrCreate
 933				<code>relationalModel.findOrCreate(attributes&lt;string|number|object&gt;, [options&lt;object&gt;])</code>
 934			</h4>
 935			<p>
 936				Returns: <q>Backbone.RelationalModel</q> A model instance.
 937			</p>
 938			<p>
 939				Search for a model instance in the <a href="#Store">Backbone.Relational.store</a>, and return the model if found.
 940				A new model will be created if no model is found, <q>attributes</q> is an object, and <q>options.create</q> is <q>true</q>.
 941			</p>
 942			<p>
 943				Accepted <q>options</q>:
 944			</p>
 945			<dl>
 946				<dt><q>create</q></dt>
 947				<dd>Default: <q>true</q>. If true, a new model will be created if an instance matching <q>attributes</q> isn't found in the store.</dd>
 948				<dt><q>merge</q></dt>
 949				<dd>Default: <q>true</q>. If true, a found model will be updated with <q>attributes</q> (if <q>attributes</q> is an <q>object</q>).</dd>
 950				<dt><q>parse</q></dt>
 951				<dd>Default: <q>false</q>. If true, <q>attributes</q> will be parsed first. Please note this will cause <q>Model.parse</q> to be called
 952				as a function (<q>this</q> will not point to a model), instead of as a method.</dd>
 953			</dl>
 954			<p class="warning">
 955				Note: this is a static method. It operates on the model type itself, not on an instance of it.
 956			</p>
 957		</section>
 958
 959		<section id="RelationalModel-find">
 960			<h4 class="code">
 961				find
 962				<code>relationalModel.find(attributes&lt;string|number|object&gt;, [options&lt;object&gt;])</code>
 963			</h4>
 964			<p>
 965				Returns: <q>Backbone.RelationalModel</q> A model instance.
 966			</p>
 967			<p>
 968				A shortcut for <a href="#RelationalModel-findOrCreate"><q>findOrCreate</q></a> that uses <q>create: false</q>.
 969				Accepts the same options as <q>findOrCreate</q> (except for <q>create</q>).
 970			</p>
 971			<p class="warning">
 972				Note: this is a static method. It operates on the model type itself, not on an instance of it.
 973			</p>
 974		</section>
 975
 976		<section id="RelationalModel-findModel">
 977			<h4 class="code">
 978				findModel
 979				<code>relationalModel.findModel(attributes&lt;string|number|object&gt;)</code>
 980			</h4>
 981			<p>
 982				Returns: <q>Backbone.RelationalModel</q> A model instance.
 983			</p>
 984			<p>
 985				A hook to override the matching when updating (or creating) a model.
 986				The default implementation is to look up the model by id in the store:
 987				<q>return Backbone.Relational.store.find( this, attributes );</q>
 988			</p>
 989			<p>
 990				Custom behavior is useful in cases where (a collection of) nested data gets saved to the server.
 991				Consider saving the following model:
 992			</p>
 993
 994<pre class="language-javascript"><code class="language-javascript runnable" data-setup="#example-zoo"><!--
 995-->var zoo = new Zoo( { id: 1, name: 'Artis', animals: [
 996	{ species: 'Giraffe' },
 997	{ species: 'Camel' }
 998] } );
 999
1000alert( JSON.stringify( zoo.toJSON(), null, 4 ) );
1001</code></pre>
1002			<p>
1003				Normally, whatever you use as server-side logic will respond by creating two animals, and assigning them
1004				an id. The response will be used by Backbone-relational to update existing models.
1005				However, updating a model starts by looking up the local model with the same id; and in this case,
1006				Backbone-relational does not know which local models corresponds to which created animal with an id.
1007				A simple fix in this case would be to add a fallback option for the matching by using the animal's
1008				species. Do note you'd want to use a more robust method usually, such as using a new model's <q>cid</q>.
1009			</p>
1010<pre class="language-javascript"><code class="language-javascript runnable" data-setup="#example-zoo"><!--
1011-->Zoo.findModel = function( attributes ) {
1012	// Try to find an instance of 'this' model type in the store
1013	var model = Backbone.Relational.store.find( this, attributes );
1014
1015	if ( !model && _.isObject( attributes ) ) {
1016		var coll = Backbone.Relational.store.getCollection( this );
1017
1018		model = coll.find( function( m ) {
1019			return m.species === attributes.species;
1020		});
1021	}
1022
1023	return model;
1024};
1025</code></pre>
1026			<p class="warning">
1027				Note: this is a static method. It operates on the model type itself, not on an instance of it.
1028			</p>
1029		</section>
1030
1031		<section id="RelationalModel-events">
1032			<h4>
1033				Catalog of Events
1034			</h4>
1035			<p>
1036				Backbone-relational makes a couple of additional events available to you, on top of	the events already found in Backbone.
1037			</p>
1038
1039			<ul class="small">
1040				<li>
1041					An <strong>"add"</strong> event is triggered on addition to a HasMany relation. Bind to:<br/>
1042					<q>add:&lt;key&gt;</q> &rarr;<code>function(addedModel&lt;Backbone.Model&gt;, related&lt;Backbone.Collection&gt;)</code>
1043				</li>
1044				<li>
1045					A <strong>"remove"</strong> event is triggered on removal from a HasMany relation. Bind to:<br/>
1046					<q>remove:&lt;key&gt;</q> &rarr;<code>function(removedModel&lt;Backbone.Model&gt;, related&lt;Backbone.Collection&gt;)</code>
1047				</li>
1048				<li>
1049					A <strong>"change"</strong> event is triggered on changes to the contents of both HasOne and HasMany relations. Bind to:<br/>
1050					<q>change:&lt;key&gt;</q> &rarr;<code>function(model&lt;Backbone.Model&gt;, related&lt;Backbone.Model|Backbone.Collection&gt;)</code>
1051				</li>
1052			</ul>
1053		</section>
1054	</section>
1055		
1056	<section id="Relation">
1057		<h2 >Backbone.Relation</h2>
1058		<p>
1059			Each <a href="#RelationalModel-relations">relation</a> definition on a model is used to create in instance of a <q>Backbone.Relation</q>; either
1060			a <q>Backbone.HasOne</q> or a <q>Backbone.HasMany</q>.
1061		</p>
1062
1063		<h4 class="code" id="Relation-HasOne">
1064			Backbone.HasOne
1065		</h4>
1066		<p>
1067			Defines a <strong>HasOne</strong> relation. When defining a <a href="#relations-reverseRelation">reverseRelation</a>, the default type
1068			will be <strong>HasMany</strong>. However, this can also be set to <strong>HasOne</strong> to define a one-to-one relation.
1069		</p>
1070
1071		<h4 class="code" id="Relation-HasMany">
1072			Backbone.HasMany
1073		</h4>
1074		<p>
1075			Defines a <strong>HasMany</strong> relation. When defining a <a href="#relations-reverseRelation">reverseRelation</a>, the type
1076			will be <strong>HasOne</strong>.
1077		</p>
1078	</section>
1079
1080	<section id="Store">
1081		<h2 >Backbone.Store</h2>
1082		<p>
1083			<strong>Backbone.Store</strong> is a global model cache. Per application, one instance is created (much like <q>Backbone.History</q>),
1084			which is accessible as <q>Backbone.Relational.store</q>.
1085		</p>
1086
1087		<h4 class="code" id="Store-addModelScope">
1088			addModelScope<code>Backbone.Relational.store.addModelScope(scope&lt;object&gt;)</code>
1089		</h4>
1090		<p>
1091			Add a namespace on which models and collections are defined. This is especially useful when working in an
1092			environment without a shared global scope (like <q>window</q> is in a browser), where you'll need to tell
1093			the <q>store</q> where your models are defined, so it can resolve them to create and maintain relations.
1094		</p>
1095
1096		<h4 class="code" id="Store-removeModelScope">
1097			removeModelScope<code>Backbone.Relational.store.removeModelScope()</code>
1098		</h4>
1099		<p>
1100			Remove a scope. This allows you to remove a scope you added previously, or to remove the default 'global'
1101			scope (<q>window</q> in the browser) scope to prevent Backbone-relational from resolving objects on it.
1102		</p>
1103
1104		<h4 class="code" id="Store-reset">
1105			reset<code>Backbone.Relational.store.reset()</code>
1106		</h4>
1107		<p>
1108			Reset the <q>store</q> to its original state. This will disable relations for all models created up to this point,
1109			remove added model scopes, and removed all internal store collections.
1110		</p>
1111
1112		<h4 class="code" id="Store-unregister">
1113			unregister<code>Backbone.Relational.store.unregister(type&lt;Backbone.RelationalModel|Backbone.RelationalModel.constructor|Backbone.Collection&gt;)</code>
1114		</h4>
1115		<p>
1116			Unregister a single model or a collection. Unregistering a model will remove a model from any relations it's involved in.
1117			Internally, unregister is called when a model has been destroyed. It can also be called explicitly to on models
1118			you don't want Backbone-relational to consider for relations anymore, for example to free up models used as (temporary) search results.
1119		</p>
1120	</section>
1121
1122	<section id="examples">
1123		<h2 >Examples</h2>
1124		<p>
1125			<a href="http://antoviaque.org/docs/tutorials/backbone-relational-tutorial/">A tutorial by antoviaque</a>,
1126			and the <a href="https://github.com/antoviaque/backbone-relational-tutorial">accompanying git repository</a>.
1127		</p>
1128		<p>
1129			A basic working example to get you started:
1130		</p>
1131		
1132<pre class="language-javascript"><code id="example-person-run1" class="language-javascript runnable" data-setup="#example-person"><!--
1133-->var paul = new Person({
1134	id: 'person-1',
1135	name: 'Paul',
1136	user: { id: 'user-1', login: 'dude', email: 'me@gmail.com' }
1137});
1138
1139// A User object is automatically created from the JSON; so 'login' returns 'dude'.
1140paul.get('user').get('login');
1141
1142var ourHouse = new House({
1143	id: 'house-1',
1144	location: 'in the middle of the street',
1145	occupants: ['person-1', 'person-2', 'person-5']
1146});
1147
1148// 'ourHouse.occupants' is turned into a Backbone.Collection of Persons.
1149// The first person in 'ourHouse.occupants' will point to 'paul'.
1150ourHouse.get('occupants').at(0); // === paul
1151
1152// If a collection is created from a HasMany relation, it contains a reference
1153// back to the originator of the relation
1154ourHouse.get('occupants').livesIn; // === ourHouse
1155
1156// The `occupants` relation on 'House' has been defined as a HasMany, with a reverse relation
1157// to `livesIn` on 'Person'. So, 'paul.livesIn' will automatically point back to 'ourHouse'.
1158paul.get('livesIn'); // === ourHouse
1159
1160// You can control which relations get serialized to JSON, using the 'includeInJSON'
1161// property on a Relation. Also, each object will only get serialized once to prevent loops.
1162alert( JSON.stringify( paul.get('user').toJSON(), null, '\t' ) );
1163</code></pre>
1164<pre class="language-javascript nomargin"><code id="example-person-run2" class="language-javascript runnable" data-setup="#example-person-run1"><!--
1165-->// Load occupants 'person-2' and 'person-5', which don't exist yet, from the server
1166ourHouse.getAsync( 'occupants' );
1167
1168// Use the `add` and `remove` events to listen for additions/removals on a HasMany relation.
1169// Here, we listen for changes to `ourHouse.occupants`.
1170ourHouse
1171	.on( 'add:occupants', function( model, coll ) {
1172		console.log( 'add %o', model );
1173		// Do something. Create a View?
1174	})
1175	.on( 'remove:occupants', function( model, coll ) {
1176		console.log( 'remove %o', model );
1177		// Do somehting. Destroy a View?
1178	});
1179
1180// Use the 'update' event to listen for changes on a HasOne relation (like 'Person.livesIn').
1181paul.on( 'change:livesIn', function( model, attr ) {
1182	console.log( 'change `livesIn` to %o', attr );
1183});
1184
1185// Modifying either side of a bi-directional relation updates the other side automatically.
1186// Take `paul` out or `ourHouse`; this triggers `remove:occupants` on `ourHouse`,
1187// and `change:livesIn` on `paul`
1188ourHouse.get( 'occupants' ).remove( paul );
1189
1190alert( 'paul.livesIn=' + paul.get( 'livesIn' ) );
1191</code></pre>
1192<pre class="language-javascript nomargin"><code id="example-person-run3" class="language-javascript runnable" data-setup="#example-person-run2"><!--
1193-->// Move into `theirHouse`; triggers 'add:occupants' on ourHouse, and 'change:livesIn' on paul
1194theirHouse = new House( { id: 'house-2' } );
1195paul.set( { 'livesIn': theirHouse } );
1196
1197alert( 'theirHouse.occupants=' + theirHouse.get( 'occupants' ).pluck( 'name' ) );
1198</code></pre>
1199
1200	<p>This is achieved using the following relations and models:</p>
1201
1202<pre class="language-javascript"><code class="language-javascript" id="example-person"><!--
1203-->House = Backbone.RelationalModel.extend({
1204	// The 'relations' property, on the House's prototype. Initialized separately for each
1205	// instance of House. Each relation must define (as a minimum) the 'type', 'key' and
1206	// 'relatedModel'. Options include 'includeInJSON', 'createModels' and 'reverseRelation'.
1207	relations: [
1208		{
1209			type: Backbone.HasMany, // Use the type, or the string 'HasOne' or 'HasMany'.
1210			key: 'occupants',
1211			relatedModel: 'Person',
1212			includeInJSON: Backbone.Model.prototype.idAttribute,
1213			collectionType: 'PersonCollection',
1214			reverseRelation: {
1215				key: 'livesIn'
1216			}
1217		}
1218	]
1219});
1220
1221Person = Backbone.RelationalModel.extend({
1222	relations: [
1223		{ // Create a (recursive) one-to-one relationship
1224			type: Backbone.HasOne,
1225			key: 'user',
1226			relatedModel: 'User',
1227			reverseRelation: {
1228				type: Backbone.HasOne,
1229				key: 'person'
1230			}
1231		}
1232	],
1233
1234	initialize: function() {
1235		// do whatever you want :)
1236	}
1237});
1238
1239PersonCollection = Backbone.Collection.extend({
1240	url: function( models ) {
1241		// Logic to create a url for the whole collection, or a set of models.
1242		// See the tests, or Backbone-tastypie, for an example.
1243		return '/person/' + ( models ? 'set/' + _.pluck( models, 'id' ).join(';') + '/' : '' );
1244	}
1245});
1246
1247User = Backbone.RelationalModel.extend();
1248</code></pre>
1249	</section>
1250
1251	<section id="change-log">
1252		<h2>Change Log</h2>
1253
1254		<h4>Master
1255			<small>
1256				<span class="date">(future)</span> &ndash;
1257				<a href="https://github.com/PaulUithol/Backbone-relational/compare/0.8.8...master">diff</a> &ndash;
1258				<a href="https://raw.github.com/PaulUithol/Backbone-relational/master/backbone-relational.js">download</a>
1259			</small>
1260		</h4>
1261		<ul>
1262			<li>
1263				<a href="https://github.com/PaulUithol/Backbone-relational/commit/42b158d8ad5697a955a2c1e615824109dfc52234"><q>42b158d</q></a>
1264				Add <q>getIdsToFetch</q> to <q>Backbone.RelationalModel</q>.
1265			</li>
1266			<li>
1267				<a href="https://github.com/PaulUithol/Backbone-relational/commit/b7e71237d1218eec41ce69e1cf56e5eecdc96bef"><q>b7e7123</q></a>
1268				<q>getAsync</q> (the successor of <q>fetchRelated</q>) now return a single promise, instead of an array of request objects.
1269			</li>
1270			<li>
1271				<a href="https://github.com/PaulUithol/Backbone-relational/issues/467"><q>#467</q></a>:
1272				Improve lazy loading implemenatation. Add <q>getAsync</q> to <q>Backbone.RelationalModel</q>, which always
1273				return a single promise that resolves with the attribute's conten…

Large files files are truncated, but you can click here to view the full file