emberjs/data — pull request #1234 by ssured (2013-09-06 14:15:23+00:00)
Title: Added support for embedded records

Adds embedded record support to the REST serializer
===================================================

The implemented strategy for handling embedded records is by creating unique deterministic IDs for these records

Consider the following data model

```js
App.Person = DS.Model.extend({
name: DS.attr('string')
});

App.Comment = DS.Model.extend({
body: DS.attr('string')
})

App.Post = DS.Model.extend({
body: DS.attr('string'),
author: DS.belongsTo('person', {embedded:true}),
comments: DS.hasMany('comment', {embedded:true})
});
```

Embedded: belongsTo
-------------------

JSON from server:

```js
{
"posts": [{
"id": "p1",
"body": "Text",
"author": {
"name": "ssured"
}
}]
}
```

Will be extracted into:

```js
{
"posts": [{
"id": "p1",
"body": "Text",
"author": "p1.author",
}],
"people": [{
"id": "p1.author",
"name": "ssured"
}]
}
```

After loading you can work with the objects in the usual way

```js
post = store.find('post','p1')
post.get('author.name') == 'ssured'
```

Embedded: hasMany
-------------------

The hasMany relation is a little special in the way it has to be sent from the server. Instead
of an array of objects, an object of objects is needed. The keys of this object will be used
to create the unique internal ids, but have no other meaning. Important is to implement some server
logic so that each embedded record always has the same key.

JSON from server:

```js
{
"posts": [{
"id": "p1",
"body": "Text",
"comments": {
"c1": {
"body": "Comment1"
},
"c2": {
"body": "Comment2"
}
}
}]
}
```

Will be extracted into:

```js
{
"posts": [{
"id": "p1",
"body": "Text",
"comments": ["p1.comments[c1]", "p1.comments[c2]"],
}],
"comments": [{
"id": "p1.comments[c1]",
"name": "Comment1"
}, {
"id": "p1.comments[c1]",
"name": "Comment2"
}]
}
```

Discussion:
-----------
- Should it also be allowed to supply embedded hasMany inside an array and use the array index as internal index
- Currently empty embedded relations are not stored in the data sent to the server, should there
be an option to set `null` value for empty belongsTo and `[]` for empty hasMany?

Implementation limitations:
---------------------------
- nowhere in your app you can use ids which start with the `embeddedIdPrefix`, which defaults to ''
- order of hasMany relations is not guaranteed to be the same as the order provided in the json from the server

TODO Incomplete implementation:
-------------------------------
- add support for polymorphic relations
- support for the various formats of server data. Sometimes the root elements have a singular key with a single object,
sometimes plural with an array.
- add alternative strategies for the hasMany relation to determine a unique key based in the index?
- isDirty properties fail to update for embedded records. This probably needs changes to the store itself
- you can still `.save()` on embedded records, which will be sent to the backend, but be careful here as it might lead to unexpected results
- no tests are added