diff --git a/assets/scripts/app/models/build.coffee b/assets/scripts/app/models/build.coffee index de4b46f6..c0f86ecd 100644 --- a/assets/scripts/app/models/build.coffee +++ b/assets/scripts/app/models/build.coffee @@ -71,7 +71,7 @@ require 'travis/model' requeue: -> Travis.ajax.post '/requests', build_id: @get('id') - isAttributeLoaded: (key) -> + isPropertyLoaded: (key) -> if ['_duration', 'finishedAt'].contains(key) && !@get('isFinished') return true else diff --git a/assets/scripts/app/models/job.coffee b/assets/scripts/app/models/job.coffee index 779cb8d5..d9a6a666 100644 --- a/assets/scripts/app/models/job.coffee +++ b/assets/scripts/app/models/job.coffee @@ -22,10 +22,10 @@ require 'travis/model' repoSlugDidChange: (-> if slug = @get('repoSlug') - @get('store').loadIncomplete(Travis.Repo, { + Travis.Repo.load([{ id: @get('repoId'), slug: slug - }, { skipIfExists: true }) + }]) ).observes('repoSlug') log: ( -> @@ -98,7 +98,7 @@ require 'travis/model' Travis.pusher.unsubscribe "job-#{@get('id')}" ).observes('state') - isAttributeLoaded: (key) -> + isPropertyLoaded: (key) -> if ['finishedAt'].contains(key) && !@get('isFinished') return true else if key == 'startedAt' && @get('state') == 'created' diff --git a/assets/scripts/lib/travis/adapter.coffee b/assets/scripts/lib/travis/adapter.coffee new file mode 100644 index 00000000..ca92965a --- /dev/null +++ b/assets/scripts/lib/travis/adapter.coffee @@ -0,0 +1,55 @@ +Travis.Adapter = Ember.RESTAdapter.extend + ajax: (url, params, method) -> + Travis.ajax.ajax(url, method || 'get', data: params) + + findMany: (klass, records, ids) -> + url = @buildURL(klass) + '?' + ids.map( (id) -> "ids[]=#{id}" ).join('&') + + self = this + @ajax(url).then (data) -> + self.didFindMany(klass, records, data) + + didFindMany: (klass, records, data) -> + collectionKey = Ember.get(klass, 'collectionKey') + dataToLoad = if collectionKey then data[collectionKey] else data + + @sideload(klass, data) + records.load(klass, dataToLoad) + + buildURL: -> + @_super.apply(this, arguments).replace(/\.json$/, '') + + didFind: (record, id, data) -> + @sideload(record.constructor, data) + @_super(record, id, data) + + didFindAll: (klass, records, data) -> + @sideload(klass, data) + @_super(klass, records, data) + + didFindQuery: (klass, records, params, data) -> + @sideload(klass, data) + @_super(klass, records, params, data) + + didCreateRecord: (record, data) -> + @sideload(record.constructor, data) + @_super(record, data) + + didSaveRecord: (record, data) -> + @sideload(record.constructor, data) + @_super(record, data) + + didDeleteRecord: (record, data) -> + @sideload(record.constructor, data) + @_super(record, data) + + sideload: (klass, data) -> + for name, records of data + records = [records] unless Ember.isArray(records) + + # we need to skip records of type, which is loaded by adapter already + if (type = Ember.get(Travis, 'mappings')[name]) && type != klass + for record in records + type.findFromCacheOrLoad(record) + + diff --git a/assets/scripts/lib/travis/model.coffee b/assets/scripts/lib/travis/model.coffee index 4587033e..4b568bee 100644 --- a/assets/scripts/lib/travis/model.coffee +++ b/assets/scripts/lib/travis/model.coffee @@ -1,41 +1,92 @@ -@Travis.Model = DS.Model.extend +get = Ember.get +set = Ember.set + +Array.prototype.diff = (a) -> + this.filter (i) -> !(a.indexOf(i) > -1) + + +@Travis.Model = Ember.Model.extend + id: Ember.attr('number') + init: -> - @loadedAttributes = [] @_super.apply this, arguments + this + + merge: (hash) -> + data = @get('_data') + Ember.merge(data, hash) + @notifyPropertyChange('_data') + + dataKey: (key) -> + meta = @constructor.metaForProperty(key) + if meta.isRelationship && !meta.options?.key? + type = meta.type + if typeof type == "string" + type = Ember.get(Ember.lookup, type) + + if meta.kind == 'belongsTo' + return type.singularName() + '_id' + else + return type.singularName() + '_ids' + + @_super(key) + + load: (id, hash) -> + @loadedAttributes = [] + @loadedRelationships = [] + + attributes = this.attributes || [] + relationships = this.relationships || [] + + for key in attributes + dataKey = @dataKey(key) + if hash.hasOwnProperty(dataKey) + @loadedAttributes.pushObject(key) + + for key in relationships + dataKey = @dataKey(key) + if hash.hasOwnProperty(dataKey) + @loadedRelationships.pushObject(key) + + incomplete = Ember.EnumerableUtils.intersection(@loadedAttributes, attributes).length != attributes.length || + Ember.EnumerableUtils.intersection(@loadedRelationships, relationships).length != relationships.length + + #if incomplete + # properties = attributes.concat(relationships) + # loadedProperties = @loadedAttributes.concat(@loadedRelationships) + # diff = properties.diff(loadedProperties) + # #console.log(@constructor, 'with id', id, 'loaded as incomplete, info:', { diff: diff, attributes: loadedProperties, data: hash}) + + @set('incomplete', incomplete) + + @_super(id, hash) getAttr: (key, options) -> @needsCompletionCheck(key) @_super.apply this, arguments getBelongsTo: (key, type, meta) -> + unless key + key = type.singularName() + '_id' @needsCompletionCheck(key) - @_super.apply this, arguments + @_super(key, type, meta) getHasMany: (key, type, meta) -> + unless key + key = type.singularName() + '_ids' @needsCompletionCheck(key) - @_super.apply this, arguments + @_super(key, type, meta) needsCompletionCheck: (key) -> - if key && (@constructor.isAttribute(key) || @constructor.isRelationship(key)) && - @get('incomplete') && !@isAttributeLoaded(key) + if key && (@isAttribute(key) || @isRelationship(key)) && + @get('incomplete') && !@isPropertyLoaded(key) @loadTheRest(key) - update: (attrs) -> - $.each attrs, (key, value) => - @set(key, value) unless key is 'id' - this + isAttribute: (name) -> + this.attributes.contains(name) - isAttributeLoaded: (name) -> - @get('store').isDataLoadedFor(this.constructor, @get('clientId'), name) - - isComplete: (-> - if @get 'incomplete' - @loadTheRest() - false - else - @set 'isCompleting', false - @get 'isLoaded' - ).property('incomplete', 'isLoaded') + isRelationship: (name) -> + this.relationships.contains(name) loadTheRest: (key) -> # for some weird reason key comes changed to a string and for some weird reason it even is called with @@ -43,32 +94,21 @@ return if !key || key == 'undefined' message = "Load missing fields for #{@constructor.toString()} because of missing key '#{key}', cid: #{@get('clientId')}, id: #{@get('id')}" - if @constructor.isAttribute('state') && key != 'state' + if @isAttribute('state') && key != 'state' message += ", in state: #{@get('state')}" console.log message return if @get('isCompleting') @set 'isCompleting', true - unless @get('stateManager.currentState.path').match /^rootState.loaded.materializing/ - @reload() - @set 'incomplete', false + @reload() select: -> @constructor.select(@get('id')) + isPropertyLoaded: (name) -> + @loadedAttributes.contains(name) || @loadedRelationships.contains(name) + @Travis.Model.reopenClass - find: -> - if arguments.length == 0 - Travis.store.findAll(this) - else - @_super.apply(this, arguments) - - filter: (callback) -> - Travis.store.filter(this, callback) - - load: (attrs) -> - Travis.store.load(this, attrs) - select: (id) -> @find().forEach (record) -> record.set('selected', record.get('id') == id) @@ -87,18 +127,21 @@ name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1) pluralName: -> - Travis.store.adapter.pluralize(@singularName()) + @singularName() + 's' - isAttribute: (name) -> - Ember.get(this, 'attributes').has(name) + collectionKey: (-> + @pluralName() + ).property() - isRelationship: (name) -> - Ember.get(this, 'relationshipsByName').has(name) + rootKey: (-> + @singularName() + ).property() - isHasManyRelationship: (name) -> - if relationship = Ember.get(this, 'relationshipsByName').get(name) - relationship.kind == 'hasMany' + isModel: (-> + true + ).property() - isBelongsToRelationship: (name) -> - if relationship = Ember.get(this, 'relationshipsByName').get(name) - relationship.kind == 'belongsTo' + isRecordLoaded: (id) -> + !!@_referenceForId(id).record + + camelizeKeys: true