-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
JSON API adapter word separator issue #974
Comments
👍 I'm having this issue also. @hugopeixoto - did you find a way around this for the time being? |
IMO - Ember Data should handle both cases, however.... AMS should provide a dasherize option also - as the spec recommends it. Rails is all about underscores, so we'd have to do something like this:
Not sure if this would even parse... |
@hhff: There's a attribute :full_name, key: "full-name" I noticed that I forgot to add my current fix to the issue. I have edited the original post with a potential workaround, if anyone runs into this problem. |
thanks @hugopeixoto ! seems like this should also be a global config, however... |
@hhff ED does, if you're using the AMS adapter... |
Thanks @bf4, thinking more about the new JSONAPI adapter, as AMS adapter is being removed from the official ember data package in favour of it. The suggestions in the above ember data thread are fine tho. I do think ams should handle this transform for us tho. |
Yeah, though we'd probably want it to be optional since people might still use AMS without a JS frontend and Rails-world still prefers underscores to dashes or camelcase. |
@hhff is it? 😅 I should stay more tuned into this! We are kind moving away from global configs, but is seems a good case. Anyway, I agree with @hhff we should handle this. |
<3 On Thu, 2 Jul 2015 at 7:40 am João Moura [email protected] wrote:
|
I was thinking a bit more about this. In my case - I'm happy for AMS to not handle this. AMS has no control of serializing attributes on the way back into the application - so it means that there has to be two layers of serialization / deserialization / normalization, whatever you want to call it, just to dasherize keys. IMO, the cleaner way to handle this is on the client (Ember makes this trivial). The Rails API "line" should be neat and clean - it should consume and deliver the same format that's in the DB wherever possible, and for Rails, dashes are a no-go. |
@hhff FYI, once we finish it, there will be no need of two layers anymore, AMS will do the magic. 😄 I partially agree with you, but for me is more about follow JSON API conventions, if this is what ppl expect when using JSON API, the adapter should provide it. But in the other hand, as you said, dashes are a no-go for Rails. Still not sure about it. |
I'm in the same scenario. Using Ember CLI and the JSON API adapter. I've also configured active_model_serializers to use the JSON API format. i.e. setting I understand Rails is all about underscores. But if ASM is set to At http://jsonapi.org/format/#document-resource-object-attributes search for For now, the solution suggested by the OP is a workaround:
|
It's goofy that the JSON API spec recommends hyphenating names, especially when this is a disallowed character for names in most languages. I definitely do think it's right to follow the spec recommendation though. AMS should default to hyphenated names, with a global option to customize the transformation. Even though, yes, Ruby and Rails use the convention of snake case, the data exchange format shouldn't be restricted to that. |
@hugopeixoto so, the https://github.com/ember-data/active-model-adapter has been extracted from ember data, but sounds like it expects ams 0.9. It might be a good idea for us to coordinate with that repo... |
@bf4 That repo is for the "vanilla" AMS format, not for the jsonapi (http://jsonapi.org) format. |
@hugopeixoto just wondering, wouldn't the fix be also needed for the relationship names? I am currently trying to use JSONapi and fear that this might bite me. |
@piotrpalek you're probably right. I'm not using relationships at the moment, so I haven't run into this. Relationship keys seem to be dasherized in ember-data as well. Relationship keys come from I suppose one could override class BaseSerializer < ActiveModel::Serializer
def transform_key key
key.to_s.dasherize.to_sym
end
def attributes *args
Hash[super.map do |key, value|
[transform_key(key), value]
end]
end
def each_association &block
super do |key, association, opts|
if block_given?
block.call transform_key(key), association, opts
end
end
end
end |
Another potential workaround, temporarily on the ember-data side: import DS from 'ember-data';
// export default DS.ActiveModelSerializer;
export default DS.JSONAPISerializer.extend({
/**
@method keyForAttribute
@param {String} key
@param {String} method
@return {String} normalized key
*/
keyForAttribute: function (key) {
return key;
},
/**
@method keyForRelationship
@param {String} key
@param {String} typeClass
@param {String} method
@return {String} normalized key
*/
keyForRelationship: function (key) {
return key;
},
}); I placed this in my ember app's Obviously, this is not ideal in the long term. |
Ember Data has exposed those hooks on purpose to account for cases like this. It's an elegant solution to the problem and IMO can be considered "the" solution here, as its normalizing both the input to Ember and the output back to Rails. Rails doesn't have to know anything about keys in this case. Tony, not sure how you're declaring keys in Ember Data models, but if you're using camel case (that's the Ember/JS way), you should use return Ember.string.underscore(key); |
Thanks @hhff and @tpitale. This workaround worked for me with the following changes/additions:
import DS from 'ember-data';
// export default DS.ActiveModelSerializer;
export default DS.JSONAPISerializer.extend({
/**
@method keyForAttribute
@param {String} key
@param {String} method
@return {String} normalized key
*/
keyForAttribute: function (key) {
return Ember.String.underscore(key);
},
/**
@method keyForRelationship
@param {String} key
@param {String} typeClass
@param {String} method
@return {String} normalized key
*/
keyForRelationship: function (key) {
return Ember.String.underscore(key);
},
});
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
pathForType: function(type) {
var underscored = Ember.String.underscore(type);
return Ember.String.pluralize(underscored);
}
}); It looks like the JSON API spec is indifferent between dashes and underscores. If the spec is indifferent then I think it'd be best to provide an option wherever it's implemented - AMS and ED. Btw, @hugopeixoto's code doesn't go far enough as it doesn't cover type values. I dasherized the value if the key == :type in attributes, but hadn't figured out where to change the type value in the relationships hash before finding the Ember Data solution above. Thanks again everyone! |
@joaomdmoura would be great to have some labels for common themes in issues: resource keys, serialization outside of a controller, testing, custom adapter, JSON API compliance, assocation issues, db queries, active record models, non-active record models (poros), upgrading, deserialization, proposing new features, asking questions (mailng list? json api forum?), refactoring, usage, who's using it, ... and in CONTRIBUTING recommend PRs/issues/commenters help identify the theme I just looked up a bunch of testing-related issues to reference in #1101 |
Fixed using this workaround: rails-api/active_model_serializers#974 (comment)
Fixed using this workaround: rails-api/active_model_serializers#974 (comment)
Thanks @bf4 I'll try to figure it out some new tags that we might use in order to make it easier |
btw everyone interest on this, would be awesome to have your opinion on #1029 |
+1 IMO this should be fixed on rail's side, and not on ember's. JSON API's format requires it to be dasherized instead of underscored. Yes, ember is flexible and lets you fix this, but there might be other frameworks that arent as flexible. |
Not required, recommended |
Sure, you know what I mean ;) We should assume that other parsers, adapters, serializers, etc follow recommendations. |
@joaomdmoura 👍 on what #1029 is aiming to achieve. Especially love that the default for JSON API would be dasherized. FYI, @hugopeixoto's workarounds mentioned in this issue breaks on association keys with today's release of v0.10.0.rc3. ( |
@mminkoff Thank you for that code snippet; I was able to use standard AMS without defining :key for every attribute! I'm using AMS v0.10.0.rc3 with Rails 4.2.1 and Ember 0.13. |
since we have various work arounds (ruby side and javascript side), I'm going to close this issue. Just as a recap (because this is what I'm doing) I've made the following modifications on the ember side to work with rails 4 and AMS: // serializers/application.js
// this allows for ember's JSONAPISerializer to accept underscored attributes (like what rails / ams outputs)
import Ember from 'ember';
import DS from 'ember-data';
var underscore = Ember.String.underscore;
export default DS.JSONAPISerializer.extend({
keyForAttribute: function(attr) {
return underscore(attr);
},
keyForRelationship: function(rawKey) {
return underscore(rawKey);
}
});
// adapters/application.js
// this changes the URLs ember builds from dasherized-ness to underscored_ness
import DS from 'ember-data';
import ENV from "../config/environment";
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
export default DS.JSONAPIAdapter.extend(DataAdapterMixin, {
namespace: 'api',
host: ENV.host,
authorizer: 'authorizer:application',
pathForType: function(type) {
let underscored = Ember.String.underscore(type);
return Ember.String.pluralize(underscored);
}
}); A guide for rails 5 can be found here http://emberigniter.com/modern-bridge-ember-and-rails-5-with-json-api/ The options brought up in this issue about customizing format on the AMS side are brought up in other issues. :-) |
Docs pr? Howto code and links? B mobile phone
|
..instead of dashes in attributes as well as relations Further information, see this: rails-api/active_model_serializers#974
An alternative Rails side solution, I took the answer to this post for creating a json params parser transform: http://stackoverflow.com/a/30557924/80050 .. and modified it to work with JSONAPI mime type giving me this (for Rails 4):
|
You can now set it globally, config/active_model_serializers.rb: ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi https://github.com/rails-api/active_model_serializers/blob/master/docs/general/key_transforms.md |
I'm using the JSON API adapter with ember-data and I'm having a small compatibility issue.
The new JSON API adapter currently does not transform the attribute keys in any way. I have an attribute with an underscore in my model, it will be left untouched. ember-data/jsonapi looks up attribute names with dash-separated words. This means that these two adapters cannot be used together without changing one of them.
The jsonapi spec does not specify that words must be dash-separated, but it does recommend it (#534 (comment), reference). ember-data follows this recommendation (emberjs/data#3455).
It would be nice to have a way to use the adapter in the recommended way.
Should this transformation be handled specifically by the jsonapi adapter?
Or should AMS provide a general key transformation option (this feature dropped on 0.10.x: #534)?
EDIT:
My current workaround was to define a base serializer, from which the actual serializers inherit:
The text was updated successfully, but these errors were encountered: