Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX release] Normalize attrs keys #3910

Merged
merged 1 commit into from
Nov 11, 2015
Merged

Conversation

fsmanuel
Copy link
Contributor

@fsmanuel fsmanuel commented Nov 6, 2015

The JSONAPISerializer expects

attrs: {
  'first-name': 'firstname'
}

The PR fixes that and now both (dasherized and camelized) work

attrs: {
  'first-name': 'firstname',
  lastName: 'lastname'
}

It also fixes #3879 but it breaks a test. I wonder if the test is intentional because it declares a relationship mapping that uses keyForAttribute to normalize it. I added a test for an attribute but I'm worried to remove the (wrong) test.

I added two comments where I would add a deprecation if the attrs key includes a dash.

@wecc @bmac can you review?

@wecc
Copy link
Contributor

wecc commented Nov 8, 2015

Thanks for the PR @fsmanuel! Can you shed some light on why this would be needed?

The JSONAPISerializer expects

 attrs: {
   'first-name': 'firstname'
}

This feels wrong to me. The first string is the name of your model's attribute, the second string is the name of the payload key (equivalent to 'first-name: { key: 'firstname' }'). You'd probably never want to declare your attributes dasherized though.

By looking at the test an attribute named last-name and lastName would collide and be considered the same? That's probably not something we want to do.

Would love to know more about the use-case needing this :)

@fsmanuel
Copy link
Contributor Author

fsmanuel commented Nov 9, 2015

@wecc you are right, it feels wrong. The dasherized version is the current behavior. I wasn't sure if we want to break that behavior (obviously it is wrong but has been the only way). I'm happy to remove it and add an error if we detect dasherized attrs keys.

@wecc
Copy link
Contributor

wecc commented Nov 9, 2015

@fsmanuel payload keys (attributes and relationships) with JSONAPISerializer defaults to dasherized but the serializer has no preference on what the model attributes looks like.

What's the problem this PR is trying to solve? Sorry if I'm missing something obvious here.

@fsmanuel
Copy link
Contributor Author

fsmanuel commented Nov 9, 2015

As discussed with @wecc on Slack the intended behavior should be to check if the attrs key is present in the models attributes or relationships. We should log a warning if a key in attrs is not present in one of the Maps.

We can use something like:

_attributesOrRelationshipsHas(typeClass, key) {
  const has = get(typeClass, 'attributes').has(key) || get(typeClass, 'relationshipsByName').has(key);
  Ember.assert('There is no attribute or relationship with the name `' + key + '`. Check your serializers attrs hash.', has);

  return has;
}

If you are ok with it. I'll update the PR later.

@fsmanuel
Copy link
Contributor Author

fsmanuel commented Nov 9, 2015

@wecc or @bmac does the snapshot has access to the typeClass? If so we could build that check into _getMappedKey. I think that would be the best place to validate the attrs key exists on the model.

@bmac
Copy link
Member

bmac commented Nov 9, 2015

@fsmanuel I think you can access the typeClass using snapshot.record.constructor.

@wecc
Copy link
Contributor

wecc commented Nov 9, 2015

Also snapshot.type

@fsmanuel
Copy link
Contributor Author

fsmanuel commented Nov 9, 2015

Perfect. Will update the PR.

@fsmanuel
Copy link
Contributor Author

@wecc updated. I also fixed my mistake that led to the RESTSerializer test failing.

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think its possible for this assertion to get triggered since it looks like _getMappedKey always gets called in a eachAttribute or eachRelationship loop.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind I see it being called in normalizeUsingDeclaredMapping

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move the code from line 762 and 763 into the assert so it will be stripped correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wecc good point.

@wecc
Copy link
Contributor

wecc commented Nov 11, 2015

Left a comment about the assert, other than that it looks good.

if (!hash.hasOwnProperty(payloadKey)) { continue; }

if (payloadKey !== key) {
hash[key] = hash[payloadKey];
// we need to normalize for JSONAPISerializer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment should be removed as this is not really JSONAPISerializer specific. You would encounter this issue with any serializer where you customize keyForAttribute/keyForRelationship to not just pass through.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true!

@fsmanuel
Copy link
Contributor Author

updated.

@bmac
Copy link
Member

bmac commented Nov 11, 2015

Thanks @fsmanuel do you mind squashing this pr into 1 commit?

@fsmanuel
Copy link
Contributor Author

@bmac i never did that before but it worked ;)

bmac added a commit that referenced this pull request Nov 11, 2015
[BUGFIX release] Normalize attrs keys
@bmac bmac merged commit aa18100 into emberjs:master Nov 11, 2015
@bmac
Copy link
Member

bmac commented Nov 11, 2015

Thanks @fsmanuel

@fsmanuel fsmanuel deleted the fix/attrs-key branch November 11, 2015 22:14
@fsmanuel
Copy link
Contributor Author

@wecc @bmac thanks for the help and feedback.

@ghost
Copy link

ghost commented Nov 17, 2015

This change has caused our app to have a huge number of warnings now for seemingly unrelated models, that didn't occur in the 2.2.0.beta.3:

WARNING: There is no attribute or relationship with the name `surveyType` on `user`. Check your serializers attrs hash.

But surveyType is not defined on user at all?

import DS from 'ember-data';

export default DS.Model.extend({
  email: DS.attr('string'),
  super: DS.attr('boolean', { defaultValue() { return false; }}),
  firstName: DS.attr('string'),
  lastName: DS.attr('string')
});

My feeling is this is to do with active-model-adapter?

@wecc
Copy link
Contributor

wecc commented Nov 17, 2015

@Soliah what does your serializer look like? I suspect you have surveyType in your attrs key in the serializer.

@ghost
Copy link

ghost commented Nov 17, 2015

@wecc ah right, we do have that in there. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants