Skip to content

Commit

Permalink
[BUGFIX release] Make sure attrs keys match model attribute names
Browse files Browse the repository at this point in the history
  • Loading branch information
fsmanuel committed Nov 10, 2015
1 parent 7a9cd27 commit 7ea8251
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 30 deletions.
17 changes: 3 additions & 14 deletions packages/ember-data/lib/serializers/json-api-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,6 @@ const JSONAPISerializer = JSONSerializer.extend({
@param {Object} attribute
*/
serializeAttribute: function(snapshot, json, key, attribute) {
// TODO deprecation if key contains -

const type = attribute.type;

if (this._canSerialize(key)) {
Expand All @@ -389,16 +387,7 @@ const JSONAPISerializer = JSONSerializer.extend({
value = transform.serialize(value);
}

let payloadKey;

const normalizedKey = this.keyForAttribute(key);
const normalizedPayloadKey = this._getMappedKey(normalizedKey);

if (normalizedKey !== normalizedPayloadKey) {
payloadKey = normalizedPayloadKey;
} else {
payloadKey = this._getMappedKey(key);
}
let payloadKey = this._getMappedKey(key, snapshot.type);

if (payloadKey === key) {
payloadKey = this.keyForAttribute(key, 'serialize');
Expand All @@ -423,7 +412,7 @@ const JSONAPISerializer = JSONSerializer.extend({

json.relationships = json.relationships || {};

var payloadKey = this._getMappedKey(key);
var payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key) {
payloadKey = this.keyForRelationship(key, 'belongsTo', 'serialize');
}
Expand Down Expand Up @@ -456,7 +445,7 @@ const JSONAPISerializer = JSONSerializer.extend({

json.relationships = json.relationships || {};

var payloadKey = this._getMappedKey(key);
var payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key && this.keyForRelationship) {
payloadKey = this.keyForRelationship(key, 'hasMany', 'serialize');
}
Expand Down
22 changes: 14 additions & 8 deletions packages/ember-data/lib/serializers/json-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -710,18 +710,19 @@ export default Serializer.extend({
@method normalizeUsingDeclaredMapping
@private
*/
normalizeUsingDeclaredMapping: function(typeClass, hash) {
normalizeUsingDeclaredMapping: function(modelClass, hash) {
var attrs = get(this, 'attrs');
var payloadKey, normalizedKey, key;

if (attrs) {
for (key in attrs) {
// TODO deprecation if key contains -
payloadKey = this._getMappedKey(key, modelClass);

payloadKey = this._getMappedKey(key);
normalizedKey = this.keyForAttribute(key);
if (!hash.hasOwnProperty(payloadKey)) { continue; }

// we need to normalize for JSONAPISerializer
normalizedKey = this.keyForAttribute(key);

if (payloadKey !== normalizedKey) {
hash[normalizedKey] = hash[payloadKey];
delete hash[payloadKey];
Expand Down Expand Up @@ -752,7 +753,12 @@ export default Serializer.extend({
@param {String} key
@return {String} key
*/
_getMappedKey: function(key) {
_getMappedKey: function(key, modelClass) {
const hasAttributeKey = get(modelClass, 'attributes').has(key);
const hasRelationshipKey = get(modelClass, 'relationshipsByName').has(key);

Ember.assert('There is no attribute or relationship with the name `' + key + '` on `' + modelClass.modelName + '`. Check your serializers attrs hash.', hasAttributeKey || hasRelationshipKey);

var attrs = get(this, 'attrs');
var mappedKey;
if (attrs && attrs[key]) {
Expand Down Expand Up @@ -1065,7 +1071,7 @@ export default Serializer.extend({

// if provided, use the mapping provided by `attrs` in
// the serializer
var payloadKey = this._getMappedKey(key);
var payloadKey = this._getMappedKey(key, snapshot.type);

if (payloadKey === key && this.keyForAttribute) {
payloadKey = this.keyForAttribute(key, 'serialize');
Expand Down Expand Up @@ -1110,7 +1116,7 @@ export default Serializer.extend({

// if provided, use the mapping provided by `attrs` in
// the serializer
var payloadKey = this._getMappedKey(key);
var payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key && this.keyForRelationship) {
payloadKey = this.keyForRelationship(key, "belongsTo", "serialize");
}
Expand Down Expand Up @@ -1162,7 +1168,7 @@ export default Serializer.extend({
if (hasMany !== undefined) {
// if provided, use the mapping provided by `attrs` in
// the serializer
var payloadKey = this._getMappedKey(key);
var payloadKey = this._getMappedKey(key, snapshot.type);
if (payloadKey === key && this.keyForRelationship) {
payloadKey = this.keyForRelationship(key, "hasMany", "serialize");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var env, store, serializer;
var get = Ember.get;
var run = Ember.run;

var User, Handle, GithubHandle, TwitterHandle, Company;
var User, Handle, GithubHandle, TwitterHandle, Company, Project;

module('integration/serializers/json-api-serializer - JSONAPISerializer', {
setup: function() {
Expand Down Expand Up @@ -32,14 +32,19 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', {
employees: DS.hasMany('user', { async: true })
});

Project = DS.Model.extend({
'company-name': DS.attr('string')
});

env = setupStore({
adapter: DS.JSONAPIAdapter,

user: User,
handle: Handle,
'github-handle': GithubHandle,
'twitter-handle': TwitterHandle,
company: Company
company: Company,
project: Project
});

store = env.store;
Expand Down Expand Up @@ -126,7 +131,6 @@ test('Serializer should respect the attrs hash when extracting attributes and re
env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
attrs: {
firstName: 'firstname_attribute_key',
'last-name': 'lastname_attribute_key',
title: "title_attribute_key",
company: { key: 'company_relationship_key' }
}
Expand All @@ -138,7 +142,6 @@ test('Serializer should respect the attrs hash when extracting attributes and re
id: '1',
attributes: {
'firstname_attribute_key': 'Yehuda',
'lastname_attribute_key': 'Katz',
'title_attribute_key': 'director'
},
relationships: {
Expand All @@ -159,7 +162,6 @@ test('Serializer should respect the attrs hash when extracting attributes and re
var user = env.store.serializerFor("user").normalizeResponse(env.store, User, jsonHash, '1', 'findRecord');

equal(user.data.attributes.firstName, 'Yehuda');
equal(user.data.attributes.lastName, 'Katz');
equal(user.data.attributes.title, "director");
deepEqual(user.data.relationships.company.data, { id: "2", type: "company" });
});
Expand All @@ -168,7 +170,6 @@ test('Serializer should respect the attrs hash when serializing attributes and r
env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
attrs: {
firstName: 'firstname_attribute_key',
'last-name': 'lastname_attribute_key',
title: "title_attribute_key",
company: { key: 'company_relationship_key' }
}
Expand All @@ -186,13 +187,51 @@ test('Serializer should respect the attrs hash when serializing attributes and r
}
});
company = env.store.peekRecord('company', 1);
user = env.store.createRecord('user', { firstName: "Yehuda", lastName: 'Katz', title: "director", company: company });
user = env.store.createRecord('user', { firstName: "Yehuda", title: "director", company: company });
});

var payload = env.store.serializerFor("user").serialize(user._createSnapshot());

equal(payload.data.relationships['company_relationship_key'].data.id, "1");
equal(payload.data.attributes['firstname_attribute_key'], 'Yehuda');
equal(payload.data.attributes['lastname_attribute_key'], 'Katz');
equal(payload.data.attributes['title_attribute_key'], "director");
});

test('Serializer should respect the attrs hash when extracting attributes with not camelized keys', function() {
env.registry.register('serializer:project', DS.JSONAPISerializer.extend({
attrs: {
'company-name': 'company_name'
}
}));

var jsonHash = {
data: {
type: 'projects',
id: '1',
attributes: {
'company_name': 'Tilde Inc.'
}
}
};

var project = env.store.serializerFor('project').normalizeResponse(env.store, User, jsonHash, '1', 'findRecord');

equal(project.data.attributes['company-name'], 'Tilde Inc.');
});

test('Serializer should respect the attrs hash when serializing attributes with not camelized keys', function() {
env.registry.register('serializer:project', DS.JSONAPISerializer.extend({
attrs: {
'company-name': 'company_name'
}
}));
var project;

run(function() {
project = env.store.createRecord('project', { 'company-name': 'Tilde Inc.' });
});

var payload = env.store.serializerFor('project').serialize(project._createSnapshot());

equal(payload.data.attributes['company_name'], 'Tilde Inc.');
});

0 comments on commit 7ea8251

Please sign in to comment.