Does anyone know of a way to specify for an Ember model
an attribute which is not persisted?
Basically, we\'re loading some metadata related to each model
Following this answer, to prevent a field from being serialized, override the default serializer for your model:
In app/serializers/person.js
:
export default DS.JSONSerializer.extend({
attrs: {
admin: { serialize: false }
}
});
See here for the source PR. This solution works in Ember Data 2, and should work in older versions as well.
When this PR get's merged it will be possible to flag properties as readOnly
. But till then there are some workarounds to this, e.g. overriding your addAttributes
method in the Adapter and deal with your special properties, here an example how this could look like:
Define your Model by adding the new option readOnly
:
App.MyModel = DS.Model.extend({
myMetaProperty: DS.attr('metaProperty', {readOnly: true})
});
and then on the Adapter:
App.Serializer = DS.RESTSerializer.extend({
addAttributes: function(data, record) {
record.eachAttribute(function(name, attribute) {
if (!attribute.options.readOnly) {
this._addAttribute(data, record, name, attribute.type);
}
}, this);
}
});
what this does is to loop over the attributes of your model and when it find's an attribute with the readOnly
flag set it skips the property.
I hope this mechanism works for your use case.
This answer is most likely out of date with the current releases of Ember Data. I wouldn't use anything in my answer.
I'm answering this question for reference, and because your comment indicated that the record remains isDirty
, but here is my solution for read-only, non-persistent, non-dirty attributes.
Overriding the addAtributes
method in your Serializer prevents readOnly
attributes from being sent to the server, which is probably exactly what you want, but you need to extend (or reopen
) your adapter to override the dirtyRecordsForAttributeChange
to prevent the record from becoming dirty:
App.CustomAdapter = DS.RESTAdapter.extend({
dirtyRecordsForAttributeChange: function(dirtySet, record, attrName, newValue, oldValue) {
meta = record.constructor.metaForProperty(attrName);
if (meta && meta.options.readOnly) { return; }
this._super.apply(this, arguments);
};
});
Then you can use readOnly
attributes like so:
App.User = DS.Model.extend({
name: DS.attr('string', {readOnly: true})
});
user = App.User.find(1); # => {id: 1, name: 'John Doe'}
user.set('name', 'Jane Doe'); #
user.get('isDirty') # => false
This setup is working for me.
The other answers to this question work with Ember data versions up to 0.13, and no longer work. For Ember data 1.0 beta 3 you can do:
App.ApplicationSerializer = DS.RESTSerializer.extend({
serializeAttribute: function(record, json, key, attribute) {
if (attribute.options.transient) {
return;
}
return this._super(record, json, key, attribute);
}
});
Now you can use transient attributes:
App.User = DS.Model.extend({
name: DS.attr('string', {transient: true})
});
These attributes won't be sent to the server when saving records.