diff --git a/FEATURES.md b/FEATURES.md index f3abee8ae9b..a3f2677c738 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -20,3 +20,8 @@ entry in `config/features.json`. - `ds-references` Adds references as described in [RFC 57](https://github.com/emberjs/rfcs/pull/57) + +- `ds-transform-pass-options` + + Pass options specified for a `DS.attr` to the `DS.Tranform`'s `serialize` and + `deserialize` methods (described in [RFC 1](https://github.com/emberjs/rfcs/pull/1)) diff --git a/addon/attr.js b/addon/attr.js index bf628e3f316..817f48ef82f 100644 --- a/addon/attr.js +++ b/addon/attr.js @@ -130,3 +130,35 @@ export default function attr(type, options) { } }).meta(meta); } + +// TODO add to documentation of `attr` function above, once this feature is added +// /** +// * The `options` hash is passed as second argument to a transforms' +// * `serialize` and `deserialize` method. This allows to configure a +// * transformation and adapt the corresponding value, based on the config: +// * +// * ```app/models/post.js +// * export default DS.Model.extend({ +// * text: DS.attr('text', { +// * uppercase: true +// * }) +// * }); +// * ``` +// * +// * ```app/transforms/text.js +// * export default DS.Transform.extend({ +// * serialize: function(value, options) { +// * if (options.uppercase) { +// * return value.toUpperCase(); +// * } +// * +// * return value; +// * }, +// * +// * deserialize: function(value) { +// * return value; +// * } +// * }) +// * ``` +// * +// */ diff --git a/addon/serializers/json.js b/addon/serializers/json.js index 0eb2389897a..330c7b90930 100644 --- a/addon/serializers/json.js +++ b/addon/serializers/json.js @@ -11,6 +11,8 @@ import { import { errorsArrayToHash } from "ember-data/-private/adapters/errors"; +import isEnabled from 'ember-data/-private/features'; + var get = Ember.get; var isNone = Ember.isNone; var merge = Ember.merge; @@ -185,11 +187,21 @@ export default Serializer.extend({ @return {Object} data The transformed data object */ applyTransforms(typeClass, data) { + let attributes; + if (isEnabled('ds-transform-pass-options')) { + attributes = get(typeClass, 'attributes'); + } + typeClass.eachTransformedAttribute((key, typeClass) => { if (!data.hasOwnProperty(key)) { return; } var transform = this.transformFor(typeClass); - data[key] = transform.deserialize(data[key]); + if (isEnabled('ds-transform-pass-options')) { + var transformMeta = attributes.get(key); + data[key] = transform.deserialize(data[key], transformMeta.options); + } else { + data[key] = transform.deserialize(data[key]); + } }); return data; @@ -1074,7 +1086,11 @@ export default Serializer.extend({ var value = snapshot.attr(key); if (type) { var transform = this.transformFor(type); - value = transform.serialize(value); + if (isEnabled('ds-transform-pass-options')) { + value = transform.serialize(value, attribute.options); + } else { + value = transform.serialize(value); + } } // if provided, use the mapping provided by `attrs` in diff --git a/config/features.json b/config/features.json index 82108bcfad3..23d2aaf0f1b 100644 --- a/config/features.json +++ b/config/features.json @@ -1,4 +1,5 @@ { "ds-finder-include": null, - "ds-references": null + "ds-references": null, + "ds-transform-pass-options": null } diff --git a/tests/integration/serializers/json-serializer-test.js b/tests/integration/serializers/json-serializer-test.js index b926f828593..06546974ed7 100644 --- a/tests/integration/serializers/json-serializer-test.js +++ b/tests/integration/serializers/json-serializer-test.js @@ -5,6 +5,8 @@ import {module, test} from 'qunit'; import DS from 'ember-data'; +import isEnabled from 'ember-data/-private/features'; + var Post, post, Comment, comment, Favorite, favorite, env; var run = Ember.run; @@ -904,3 +906,50 @@ test('normalizeResponse ignores unmapped attributes', function(assert) { assert.equal(post.data.attributes.title, "Rails is omakase"); }); + +if (isEnabled('ds-transform-pass-options')) { + + test('options are passed to transform for serialization', function(assert) { + assert.expect(1); + + env.registry.register('transform:custom', DS.Transform.extend({ + serialize: function(deserialized, options) { + assert.deepEqual(options, { custom: 'config' }); + } + })); + + Post.reopen({ + custom: DS.attr('custom', { + custom: 'config' + }) + }); + + var post; + run(function() { + post = env.store.createRecord('post', { custom: 'value' }); + }); + + env.serializer.serialize(post._createSnapshot()); + }); + + test('options are passed to transform for normalization', function(assert) { + assert.expect(1); + + env.registry.register('transform:custom', DS.Transform.extend({ + deserialize: function(serialized, options) { + assert.deepEqual(options, { custom: 'config' }); + } + })); + + Post.reopen({ + custom: DS.attr('custom', { + custom: 'config' + }) + }); + + env.serializer.normalize(Post, { + custom: 'value' + }); + }); + +}