Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/ember-data/lib/system/model/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ function getAttr(record, options, key) {
return value;
}

/**
Defines an attribute on a DS.Model of a specified type.
By default, data ships with four attribute types:
'string', 'number', 'boolean' and 'date'.
You can define your own transform by appending to DS.attr.transforms.

DS.attr takes an optional hash as a second parameter, currently
supported options are:
'defaultValue': Sets the attribute to a default if none is supplied by the user.
'key': Use a custom key in the JSON.
'readOnly': Do not include this attribute in the JSON representation.

@param {String} type the attribute type
@param {Object} options a hash of options
*/

DS.attr = function(type, options) {
var transform = DS.attr.transforms[type];
Ember.assert("Could not find model attribute of type " + type, !!transform);
Expand Down Expand Up @@ -67,6 +83,11 @@ DS.attr = function(type, options) {
if (arguments.length === 2) {
value = transformTo(value);

if(meta.options.readOnly){
Ember.warn("You can't set the read-only attribute: " + key);
value = getAttr(this, options, key);
}

if (value !== getAttr(this, options, key)) {
this.setProperty(key, value);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/ember-data/lib/system/model/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,17 @@ DS.Model = Ember.Object.extend(Ember.Evented, {
The default implementation gets the current value of each
attribute from the `data`, and uses a `defaultValue` if
specified in the `DS.attr` definition.
Attributes can be skipped by setting readOnly to true in
the 'DS.attr' definition.

@param {Object} json the JSON hash being build
@param {Ember.Map} attributes a Map of attributes
@param {DataProxy} data the record's data, accessed with `get` and `set`.
*/
addAttributesToJSON: function(json, attributes, data) {
attributes.forEach(function(name, meta) {
if(meta.options.readOnly){ return; }

var key = meta.key(this.constructor),
value = get(data, key);

Expand Down
22 changes: 22 additions & 0 deletions packages/ember-data/tests/unit/model_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ test("setting a property on a record that has not changed does not cause it to b
equal(person.get('isDirty'), false, "record does not become dirty after setting property to old value");
});

test("does not set a readOnly Property", function() {
Person.reopen({
foobar: DS.attr('string', {readOnly: true})
});

var record = store.createRecord(Person);
set(record, 'foobar', 'bar');

equal(get(record, 'foobar'), null, "readOnly property was not set on the record");
});

test("sets readOnly properties using store.load", function() {
Person.reopen({
foobar: DS.attr('string', {readOnly: true})
});

var record = store.load(Person, { id: 1, foobar: 'bar'});
set(record, 'foobar', 'bar');

equal(get(record, 'foobar'), 'bar', "readOnly property was loaded on the record");
});

test("a record reports its unique id via the `id` property", function() {
store.load(Person, { id: 1 });

Expand Down
22 changes: 22 additions & 0 deletions packages/ember-data/tests/unit/to_json_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,25 @@ test("custom belongsTo keys are applied", function() {
equal(json.related_id, 1, "applied standard key to JSON");
equal(json.my_custom_key, 1, "applied custom key to JSON");
});

test("toJSON respects readOnly meta", function() {
var store = DS.Store.create();

var Model = DS.Model.extend({
name: DS.attr('string'),
readOnlyName: DS.attr('string', {readOnly: true})
});

store.load(Model, {
id: 1,
name: "John Doe",
readOnlyName: 'Jane Doe'
});

var record = store.find(Model, 1);

var json = record.toJSON();

equal(json.name, "John Doe", "serialized attribute correctly");
ok(!json.hasOwnProperty('readOnlyName'), "ignored readOnly attribute");
});