Fix incomplete implementation

While testing in the wild I spotted a few problems with it:

* it didn't work for camel case names.
* it was sometimes setting loaded data too late - it needed to use find
  and then save data on the record. Instead it should save data in
  special array saved on store, indexed by clientId
* there is already method to get attributes in ember-data, it just
  doesn't work with Travis.Foo.get('attributes'), it needs
  Ember.get(Travis.Foo, 'attributes') - it makes implementation much
  shorter
This commit is contained in:
Piotr Sarnacki 2012-10-22 02:49:03 +02:00
parent 6cfddfd882
commit 300ad58516
7 changed files with 81 additions and 23 deletions

View File

@ -8,6 +8,10 @@ Travis.Store = DS.Store.extend
revision: 4
adapter: Travis.RestAdapter.create()
init: ->
@_super.apply this, arguments
@_loadedData = {}
load: (type, id, hash) ->
result = @_super.apply this, arguments
@ -75,18 +79,30 @@ Travis.Store = DS.Store.extend
# attached. I don't want to use store.sideload here as it will not use merge,
# if we need sideload becasue we have side records with other events it needs to
# be revised
if type == Travis.Build && json.repository
result = @loadIncomplete(Travis.Repo, json.repository)
if type == Travis.Build && (json.repository || json.repo)
result = @loadIncomplete(Travis.Repo, json.repository || json.repo)
@loadIncomplete(type, json[root])
addLoadedData: (type, clientId, hash) ->
id = hash.id
@_loadedData[type.toString()] ||= {}
loadedData = (@_loadedData[type][clientId] ||= [])
for key of hash
loadedData.pushObject key unless loadedData.contains(key)
isDataLoadedFor: (type, clientId, key) ->
if recordsData = @_loadedData[type.toString()]
if data = recordsData[clientId]
data.contains(key)
loadIncomplete: (type, hash) ->
result = @merge(type, hash)
if result && result.clientId
@addLoadedData(type, result.clientId, hash)
record = @findByClientId(type, result.clientId)
unless record.get('complete')
record.set 'incomplete', true
record.loadedAttributes = Object.keys hash
record.loadedAsIncomplete()
@_updateAssociations(type, type.singularName(), hash)

View File

@ -23,7 +23,9 @@
this
isAttributeLoaded: (name) ->
@loadedAttributes.contains(name)
if meta = Ember.get(this.constructor, 'attributes').get(name)
name = meta.key(this.constructor)
@get('store').isDataLoadedFor(this.constructor, @get('clientId'), name)
isComplete: (->
if @get 'incomplete'
@ -43,6 +45,9 @@
select: ->
@constructor.select(@get('id'))
loadedAsIncomplete: () ->
@set 'incomplete', true
@Travis.Model.reopenClass
find: ->
if arguments.length == 0
@ -77,15 +82,4 @@
Travis.app.store.adapter.pluralize(@singularName())
isAttribute: (name) ->
unless @attributesSaved
@_saveAttributes()
@cachedAttributes.contains(name)
_saveAttributes: ->
@attributesSaved = true
cachedAttributes = []
@eachComputedProperty (name, meta) ->
cachedAttributes.pushObject name if meta.isAttribute
@cachedAttributes = cachedAttributes
Ember.get(this, 'attributes').has(name)

View File

@ -1,6 +1,7 @@
Travis.Foo = Travis.Model.extend
name: DS.attr('string')
description: DS.attr('string')
lastName: DS.attr('string')
record = null
store = null
@ -22,6 +23,7 @@ describe 'Travis.Model', ->
attrs = {
id: 1
name: 'foo'
last_name: 'foobar'
}
record = store.loadIncomplete(Travis.Foo, attrs)
@ -51,6 +53,25 @@ describe 'Travis.Model', ->
store.loadIncomplete(Travis.Foo, id: 1)
expect( record.get('incomplete') ).toBeFalsy()
it 'does not load data on non attribute', ->
record.get('foobarbaz')
waits 50
runs ->
expect( record.get('incomplete') ).toBeTruthy()
it 'works with camel case values', ->
expect( record.get('lastName') ).toEqual 'foobar'
waits 50
runs ->
expect( record.get('complete') ).toBeFalsy()
it 'adds takes into account additional data loaded as incomplete', ->
record = store.loadIncomplete(Travis.Foo, { id: 1, description: 'baz' })
expect( record.get('description') ).toEqual 'baz'
waits 50
runs ->
expect( record.get('complete') ).toBeFalsy()
describe 'with complete record', ->
beforeEach ->
id = 5

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8873,7 +8873,8 @@ return sinon;}.call(typeof window != 'undefined' && window || {}));
Travis.Foo = Travis.Model.extend({
name: DS.attr('string'),
description: DS.attr('string')
description: DS.attr('string'),
lastName: DS.attr('string')
});
record = null;
@ -8904,7 +8905,8 @@ return sinon;}.call(typeof window != 'undefined' && window || {}));
var attrs;
attrs = {
id: 1,
name: 'foo'
name: 'foo',
last_name: 'foobar'
};
return record = store.loadIncomplete(Travis.Foo, attrs);
});
@ -8929,7 +8931,7 @@ return sinon;}.call(typeof window != 'undefined' && window || {}));
return expect(record.get('isComplete')).toBeTruthy();
});
});
return it('does not set incomplete on the record twice', function() {
it('does not set incomplete on the record twice', function() {
record.get('description');
waits(50);
return runs(function() {
@ -8939,6 +8941,31 @@ return sinon;}.call(typeof window != 'undefined' && window || {}));
return expect(record.get('incomplete')).toBeFalsy();
});
});
it('does not load data on non attribute', function() {
record.get('foobarbaz');
waits(50);
return runs(function() {
return expect(record.get('incomplete')).toBeTruthy();
});
});
it('works with camel case values', function() {
expect(record.get('lastName')).toEqual('foobar');
waits(50);
return runs(function() {
return expect(record.get('complete')).toBeFalsy();
});
});
return it('adds takes into account additional data loaded as incomplete', function() {
record = store.loadIncomplete(Travis.Foo, {
id: 1,
description: 'baz'
});
expect(record.get('description')).toEqual('baz');
waits(50);
return runs(function() {
return expect(record.get('complete')).toBeFalsy();
});
});
});
return describe('with complete record', function() {
beforeEach(function() {

View File

@ -1 +1 @@
bdcb74b8
f2588d36