Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Break up and document `toJSON`.

  • Loading branch information...
commit 3843029c69d835d247d8182a4d5645f5acedcb7e 1 parent 32d138a
tomhuda authored
View
1  packages/ember-data/lib/system/model/associations.js
@@ -38,6 +38,7 @@ DS.Model.reopenClass({
this.eachComputedProperty(function(name, meta) {
if (meta.isAssociation) {
+ meta.key = name;
type = meta.type;
if (typeof type === 'string') {
View
162 packages/ember-data/lib/system/model/model.js
@@ -131,7 +131,118 @@ DS.Model = Ember.Object.extend({
return data && get(data, primaryKey);
}).property('primaryKey', 'data'),
- // TODO: Break up this method
+ // The following methods are callbacks invoked by `getJSON`. You
+ // can override one of the callbacks to override specific behavior,
+ // or getJSON itself.
+ //
+ // If you override getJSON, you can invoke these callbacks manually
+ // to get the default behavior.
+
+ /**
+ Add the record's primary key to the JSON hash.
+
+ The default implementation uses the record's specified `primaryKey`
+ and the `id` computed property, which are passed in as parameters.
+
+ @param {Object} json the JSON hash being built
+ @param {Number|String} id the record's id
+ @param {String} key the primaryKey for the record
+ */
+ addIdToJSON: function(json, id, key) {
+ if (id) { json[key] = id; }
+ },
+
+ /**
+ Add the attributes' current values to the JSON hash.
+
+ The default implementation gets the current value of each
+ attribute from the `data`, and uses a `defaultValue` if
+ specified in the `DS.attr` definition.
+
+ @param {Object} json the JSON hash being build
+ @param {Ember.Map} attributes a Map of attributes
+ @param {DataProxy} data the record's data, accessed with `get` and `set`.
+ */
+ addAttributesToJSON: function(json, attributes, data) {
+ attributes.forEach(function(name, meta) {
+ var key = meta.options.key || name,
+ value = get(data, key);
+
+ if (value === undefined) {
+ value = meta.options.defaultValue;
+ }
+
+ json[key] = value;
+ }, this);
+ },
+
+ /**
+ Add the value of a `hasMany` association to the JSON hash.
+
+ The default implementation honors the `embedded` option
+ passed to `DS.hasMany`. If embedded, `toJSON` is recursively
+ called on the child records. If not, the `id` of each
+ record is added.
+
+ Note that if a record is not embedded and does not
+ yet have an `id` (usually provided by the server), it
+ will not be included in the output.
+
+ @param {Object} json the JSON hash being built
+ @param {DataProxy} data the record's data, accessed with `get` and `set`.
+ @param {Object} meta information about the association
+ @param {Object} options options passed to `toJSON`
+ */
+ addHasManyToJSON: function(json, data, meta, options) {
+ var key = meta.key,
+ manyArray = get(this, key),
+ records = [],
+ clientId, id;
+
+ if (meta.options.embedded) {
+ // TODO: Avoid materializing embedded hashes if possible
+ manyArray.forEach(function(record) {
+ records.push(record.toJSON(options));
+ });
+ } else {
+ var clientIds = get(manyArray, 'content');
+
+ for (var i=0, l=clientIds.length; i<l; i++) {
+ clientId = clientIds[i];
+ id = get(this, 'store').clientIdToId[clientId];
+
+ if (id !== undefined) {
+ records.push(id);
+ }
+ }
+ }
+
+ json[key] = records;
+ },
+
+ /**
+ Add the value of a `belongsTo` association to the JSON hash.
+
+ The default implementation always includes the `id`.
+
+ @param {Object} json the JSON hash being built
+ @param {DataProxy} data the record's data, accessed with `get` and `set`.
+ @param {Object} meta information about the association
+ @param {Object} options options passed to `toJSON`
+ */
+ addBelongsToToJSON: function(json, data, meta, options) {
+ var key = meta.key, id;
+
+ if (id = data.get(key)) {
+ json[key] = id;
+ }
+ },
+
+ /**
+ Create a JSON representation of the record, including its `id`,
+ attributes and associations. Honor any settings defined on the
+ attributes or associations (such as `embedded` or `key`).
+ */
toJSON: function(options) {
var data = get(this, 'data'),
result = {},
@@ -144,54 +255,21 @@ DS.Model = Ember.Object.extend({
options = options || {};
- if (id) {
- result[primaryKey] = id;
- }
-
- attributes.forEach(function(name, meta) {
- var key = meta.options.key || name,
- value = get(data, key);
-
- if (value === undefined) {
- value = meta.options.defaultValue;
- }
+ // delegate to `addIdToJSON` callback
+ this.addIdToJSON(result, id, primaryKey);
- result[key] = value;
- }, this);
+ // delegate to `addAttributesToJSON` callback
+ this.addAttributesToJSON(result, attributes, data);
associations = get(type, 'associationsByName');
+ // add associations, delegating to `addHasManyToJSON` and
+ // `addBelongsToToJSON`.
associations.forEach(function(key, meta) {
if (options.associations && meta.kind === 'hasMany') {
- var association = get(this, key),
- clientIdToIdMap = store.clientIdToId,
- clientIds = get(association, 'content'),
- records = [],
- clientId, serverId;
-
- if (meta.options.embedded) {
- association.forEach(function(record) {
- records.push(record.toJSON(options));
- });
- } else {
- for (var i=0, l=clientIds.length; i<l; i++) {
- clientId = clientIds[i];
-
- serverId = clientIdToIdMap[clientId];
-
- if (serverId !== undefined) {
- records.push(serverId);
- }
- }
- }
-
- result[key] = records;
+ this.addHasManyToJSON(result, data, meta, options);
} else if (meta.kind === 'belongsTo') {
- id = data.get(key);
-
- if (id) {
- result[key] = id;
- }
+ this.addBelongsToToJSON(result, data, meta, options);
}
}, this);
Please sign in to comment.
Something went wrong with that request. Please try again.