Summary
For Ember Data. Pass through attribute meta data, which includes parentType
, options
, name
, etc.,
to the transform associated with that attribute. This will allow provide the following function signiture updates to DS.Transform
:
transform.serialize(deserialized, attributeMeta)
transform.deserialize(serialized, attributeMeta)
Motivation
The main use case is to be able to configure the transform
on a per-model basis making more DRY code. So the transform can be aware of type and options on DS.attr
can
be useful to configure the transform for DRY use.
Detailed design
Implementing
The change will most likely start in eachTransformedAttribute
, which gets the attributes for that instance via get(this, 'attributes')
. In the forEach
the name
will be used to get the specific attribute, e.g.
var attributeMeta = attributes.get(name);
callback.call(binding, name, type, attributeMeta);
The next change will be in applyTransforms
, where the attributeMeta
parameter is added and passed to transform.deserialize
as the second argument.
You also have to handle the serialization part in serializeAttribute
, where you pass through the attribute
parameter to transform.serialize
.
Using
A convoluted example:
// Example based on https://github.com/chjj/marked library
App.PostModel = DS.Model.extend({
title: DS.attr('string'),
markdown: DS.attr('markdown', {
markdown: {
gfm: false,
sanitize: true
}
})
});
App.TechnicalPostModel = DS.Model.extend({
title: DS.attr('string'),
gistUrl: DS.attr('string'),
markdown: DS.attr('markdown', {
markdown: {
gfm: true,
tables: true,
sanitize: false
}
})
});
App.MarkdownTransform = DS.Transform.extend({
serialize: function (deserialized, attributeMeta) {
return deserialized.raw;
},
deserialize: function (serialized, attributeMeta) {
var options = attributeMeta.options.markdown || {};
return marked(serialized, options);
}
});
Drawbacks
Extra API surface area, although not much. This could also potentially introduce tight coupling between models and transforms if used improperly, e.g. not returning a default value if using type checking.
Alternatives
- Passing the information from the server, which is a poor solution.
- Writing a new transform for each model/attribute that needs a variation. Although this might be a good solution sometimes if you extend a base transform.
Unresolved questions
Does the whole meta object need to be passed, or do we selectively pass in only the useful properties? Like
options
and parentType
and name
..