ember-model-rails 0.0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/lib/ember-model-rails/version.rb +7 -0
- data/lib/ember-model-rails.rb +10 -0
- data/vendor/assets/javascripts/ember-model.js +707 -0
- data/vendor/assets/javascripts/ember-model.min.js +13 -0
- metadata +86 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alex Auritt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Ember::Model::Rails
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'ember-model-rails'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install ember-model-rails
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
@@ -0,0 +1,707 @@
|
|
1
|
+
// Last commit: 7656e63 (2013-05-28 17:06:31 -0700)
|
2
|
+
|
3
|
+
|
4
|
+
(function() {
|
5
|
+
Ember.Adapter = Ember.Object.extend({
|
6
|
+
find: function(record, id) {
|
7
|
+
throw new Error('Ember.Adapter subclasses must implement find');
|
8
|
+
},
|
9
|
+
|
10
|
+
findQuery: function(klass, records, params) {
|
11
|
+
throw new Error('Ember.Adapter subclasses must implement findQuery');
|
12
|
+
},
|
13
|
+
|
14
|
+
findMany: function(klass, records, ids) {
|
15
|
+
throw new Error('Ember.Adapter subclasses must implement findMany');
|
16
|
+
},
|
17
|
+
|
18
|
+
findAll: function(klass, records) {
|
19
|
+
throw new Error('Ember.Adapter subclasses must implement findAll');
|
20
|
+
},
|
21
|
+
|
22
|
+
load: function(record, id, data) {
|
23
|
+
record.load(id, data);
|
24
|
+
},
|
25
|
+
|
26
|
+
createRecord: function(record) {
|
27
|
+
throw new Error('Ember.Adapter subclasses must implement createRecord');
|
28
|
+
},
|
29
|
+
|
30
|
+
saveRecord: function(record) {
|
31
|
+
throw new Error('Ember.Adapter subclasses must implement saveRecord');
|
32
|
+
},
|
33
|
+
|
34
|
+
deleteRecord: function(record) {
|
35
|
+
throw new Error('Ember.Adapter subclasses must implement deleteRecord');
|
36
|
+
}
|
37
|
+
});
|
38
|
+
})();
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
(function() {
|
43
|
+
Ember.FixtureAdapter = Ember.Adapter.extend({
|
44
|
+
find: function(record, id) {
|
45
|
+
var fixtures = record.constructor.FIXTURES,
|
46
|
+
data = Ember.A(fixtures).find(function(el) { return el.id === id; });
|
47
|
+
|
48
|
+
if (!record.get('isLoaded')) {
|
49
|
+
setTimeout(function() {
|
50
|
+
Ember.run(record, record.load, id, data);
|
51
|
+
});
|
52
|
+
}
|
53
|
+
},
|
54
|
+
|
55
|
+
findMany: function(klass, records, ids) {
|
56
|
+
var fixtures = klass.FIXTURES,
|
57
|
+
requestedData = [];
|
58
|
+
|
59
|
+
for (var i = 0, l = ids.length; i < l; i++) {
|
60
|
+
requestedData.push(fixtures[i]);
|
61
|
+
}
|
62
|
+
|
63
|
+
setTimeout(function() {
|
64
|
+
Ember.run(records, records.load, klass, requestedData);
|
65
|
+
});
|
66
|
+
},
|
67
|
+
|
68
|
+
findAll: function(klass, records) {
|
69
|
+
var fixtures = klass.FIXTURES;
|
70
|
+
|
71
|
+
setTimeout(function() {
|
72
|
+
Ember.run(records, records.load, klass, fixtures);
|
73
|
+
});
|
74
|
+
},
|
75
|
+
|
76
|
+
createRecord: function(record) {
|
77
|
+
var klass = record.constructor,
|
78
|
+
fixtures = klass.FIXTURES;
|
79
|
+
|
80
|
+
setTimeout(function() {
|
81
|
+
Ember.run(function() {
|
82
|
+
fixtures.push(klass.findFromCacheOrLoad(record.toJSON()));
|
83
|
+
record.didCreateRecord();
|
84
|
+
});
|
85
|
+
});
|
86
|
+
|
87
|
+
return record;
|
88
|
+
},
|
89
|
+
|
90
|
+
saveRecord: function(record) {
|
91
|
+
var deferred = Ember.Deferred.create();
|
92
|
+
deferred.then(function() {
|
93
|
+
record.didSaveRecord();
|
94
|
+
});
|
95
|
+
setTimeout(function() {
|
96
|
+
Ember.run(deferred, deferred.resolve, record);
|
97
|
+
});
|
98
|
+
return deferred;
|
99
|
+
},
|
100
|
+
|
101
|
+
deleteRecord: function(record) {
|
102
|
+
var deferred = Ember.Deferred.create();
|
103
|
+
deferred.then(function() {
|
104
|
+
record.didDeleteRecord();
|
105
|
+
});
|
106
|
+
setTimeout(function() {
|
107
|
+
Ember.run(deferred, deferred.resolve, record);
|
108
|
+
});
|
109
|
+
return deferred;
|
110
|
+
}
|
111
|
+
});
|
112
|
+
})();
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
(function() {
|
117
|
+
var get = Ember.get,
|
118
|
+
set = Ember.set;
|
119
|
+
|
120
|
+
Ember.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, Ember.DeferredMixin, {
|
121
|
+
isLoaded: false,
|
122
|
+
isLoading: Ember.computed.not('isLoaded'),
|
123
|
+
|
124
|
+
load: function(klass, data) {
|
125
|
+
set(this, 'content', this.materializeData(klass, data));
|
126
|
+
this.notifyLoaded();
|
127
|
+
},
|
128
|
+
|
129
|
+
loadForFindMany: function(klass) {
|
130
|
+
var content = get(this, '_ids').map(function(id) { return klass.cachedRecordForId(id); });
|
131
|
+
set(this, 'content', Ember.A(content));
|
132
|
+
this.notifyLoaded();
|
133
|
+
},
|
134
|
+
|
135
|
+
notifyLoaded: function() {
|
136
|
+
set(this, 'isLoaded', true);
|
137
|
+
this.trigger('didLoad');
|
138
|
+
this.resolve(this);
|
139
|
+
},
|
140
|
+
|
141
|
+
materializeData: function(klass, data) {
|
142
|
+
return Ember.A(data.map(function(el) {
|
143
|
+
return klass.findFromCacheOrLoad(el); // FIXME
|
144
|
+
}));
|
145
|
+
}
|
146
|
+
});
|
147
|
+
})();
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
(function() {
|
152
|
+
var get = Ember.get;
|
153
|
+
|
154
|
+
Ember.FilteredRecordArray = Ember.RecordArray.extend({
|
155
|
+
init: function() {
|
156
|
+
if (!get(this, 'modelClass')) {
|
157
|
+
throw new Error('FilteredRecordArrays must be created with a modelClass');
|
158
|
+
}
|
159
|
+
if (!get(this, 'filterFunction')) {
|
160
|
+
throw new Error('FilteredRecordArrays must be created with a filterFunction');
|
161
|
+
}
|
162
|
+
if (!get(this, 'filterProperties')) {
|
163
|
+
throw new Error('FilteredRecordArrays must be created with filterProperties');
|
164
|
+
}
|
165
|
+
|
166
|
+
var modelClass = get(this, 'modelClass');
|
167
|
+
modelClass.registerRecordArray(this);
|
168
|
+
|
169
|
+
this.registerObservers();
|
170
|
+
this.updateFilter();
|
171
|
+
},
|
172
|
+
|
173
|
+
updateFilter: function() {
|
174
|
+
var self = this,
|
175
|
+
results = [];
|
176
|
+
get(this, 'modelClass').forEachCachedRecord(function(record) {
|
177
|
+
if (self.filterFunction(record)) {
|
178
|
+
results.push(record);
|
179
|
+
}
|
180
|
+
});
|
181
|
+
this.set('content', Ember.A(results));
|
182
|
+
},
|
183
|
+
|
184
|
+
updateFilterForRecord: function(record) {
|
185
|
+
var results = get(this, 'content');
|
186
|
+
if (this.filterFunction(record)) {
|
187
|
+
results.pushObject(record);
|
188
|
+
}
|
189
|
+
},
|
190
|
+
|
191
|
+
registerObservers: function() {
|
192
|
+
var self = this;
|
193
|
+
get(this, 'modelClass').forEachCachedRecord(function(record) {
|
194
|
+
self.registerObserversOnRecord(record);
|
195
|
+
});
|
196
|
+
},
|
197
|
+
|
198
|
+
registerObserversOnRecord: function(record) {
|
199
|
+
var self = this,
|
200
|
+
filterProperties = get(this, 'filterProperties');
|
201
|
+
|
202
|
+
for (var i = 0, l = get(filterProperties, 'length'); i < l; i++) {
|
203
|
+
record.addObserver(filterProperties[i], self, 'updateFilterForRecord');
|
204
|
+
}
|
205
|
+
}
|
206
|
+
});
|
207
|
+
})();
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
(function() {
|
212
|
+
var get = Ember.get,
|
213
|
+
set = Ember.set,
|
214
|
+
meta = Ember.meta;
|
215
|
+
|
216
|
+
function contains(array, element) {
|
217
|
+
for (var i = 0, l = array.length; i < l; i++) {
|
218
|
+
if (array[i] === element) { return true; }
|
219
|
+
}
|
220
|
+
return false;
|
221
|
+
}
|
222
|
+
|
223
|
+
function concatUnique(toArray, fromArray) {
|
224
|
+
var e;
|
225
|
+
for (var i = 0, l = fromArray.length; i < l; i++) {
|
226
|
+
e = fromArray[i];
|
227
|
+
if (!contains(toArray, e)) { toArray.push(e); }
|
228
|
+
}
|
229
|
+
return toArray;
|
230
|
+
}
|
231
|
+
|
232
|
+
Ember.run.queues.push('data');
|
233
|
+
|
234
|
+
Ember.Model = Ember.Object.extend(Ember.Evented, Ember.DeferredMixin, {
|
235
|
+
isLoaded: true,
|
236
|
+
isLoading: Ember.computed.not('isLoaded'),
|
237
|
+
isNew: true,
|
238
|
+
isDeleted: false,
|
239
|
+
_dirtyAttributes: null,
|
240
|
+
|
241
|
+
// TODO: rewrite w/o volatile
|
242
|
+
isDirty: Ember.computed(function() {
|
243
|
+
var attributes = this.attributes,
|
244
|
+
dirtyAttributes = this._dirtyAttributes,
|
245
|
+
key, cachedValue, dataValue, desc, descMeta, type, isDirty;
|
246
|
+
for (var i = 0, l = attributes.length; i < l; i++) {
|
247
|
+
key = attributes[i];
|
248
|
+
cachedValue = this.cacheFor(key);
|
249
|
+
dataValue = get(this, 'data.'+key);
|
250
|
+
desc = meta(this).descs[key];
|
251
|
+
descMeta = desc && desc.meta();
|
252
|
+
type = descMeta.type;
|
253
|
+
isDirty = dirtyAttributes && dirtyAttributes.indexOf(key) !== -1;
|
254
|
+
if (!isDirty && type && type.isEqual) {
|
255
|
+
if (!type.isEqual(dataValue, cachedValue || dataValue)) { // computed property won't have a value when just loaded
|
256
|
+
if (!dirtyAttributes) {
|
257
|
+
dirtyAttributes = this._dirtyAttributes = Ember.A();
|
258
|
+
}
|
259
|
+
dirtyAttributes.push(key);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
}
|
264
|
+
return dirtyAttributes && dirtyAttributes.length !== 0;
|
265
|
+
}).property().volatile(),
|
266
|
+
|
267
|
+
init: function() {
|
268
|
+
if (!get(this, 'isNew')) { this.resolve(this); }
|
269
|
+
this._super();
|
270
|
+
},
|
271
|
+
|
272
|
+
load: function(id, hash) {
|
273
|
+
var data = Ember.merge({id: id}, hash);
|
274
|
+
set(this, 'data', data);
|
275
|
+
set(this, 'isLoaded', true);
|
276
|
+
set(this, 'isNew', false);
|
277
|
+
this.trigger('didLoad');
|
278
|
+
this.resolve(this);
|
279
|
+
},
|
280
|
+
|
281
|
+
didDefineProperty: function(proto, key, value) {
|
282
|
+
if (value instanceof Ember.Descriptor) {
|
283
|
+
var meta = value.meta();
|
284
|
+
|
285
|
+
if (meta.isAttribute) {
|
286
|
+
if (!proto.attributes) { proto.attributes = []; }
|
287
|
+
proto.attributes.push(key);
|
288
|
+
}
|
289
|
+
}
|
290
|
+
},
|
291
|
+
|
292
|
+
toJSON: function() {
|
293
|
+
return this.getProperties(this.attributes);
|
294
|
+
},
|
295
|
+
|
296
|
+
save: function() {
|
297
|
+
var adapter = this.constructor.adapter;
|
298
|
+
set(this, 'isSaving', true);
|
299
|
+
if (get(this, 'isNew')) {
|
300
|
+
return adapter.createRecord(this);
|
301
|
+
} else if (get(this, 'isDirty')) {
|
302
|
+
return adapter.saveRecord(this);
|
303
|
+
} else {
|
304
|
+
var deferred = Ember.Deferred.create();
|
305
|
+
deferred.resolve(this);
|
306
|
+
return deferred;
|
307
|
+
}
|
308
|
+
},
|
309
|
+
|
310
|
+
didCreateRecord: function() {
|
311
|
+
set(this, 'isNew', false);
|
312
|
+
this.load(this.get('id'), this.getProperties(this.attributes));
|
313
|
+
this.constructor.addToRecordArrays(this);
|
314
|
+
this.trigger('didCreateRecord');
|
315
|
+
this.didSaveRecord();
|
316
|
+
},
|
317
|
+
|
318
|
+
didSaveRecord: function() {
|
319
|
+
set(this, 'isSaving', false);
|
320
|
+
this.trigger('didSaveRecord');
|
321
|
+
this._copyDirtyAttributesToData();
|
322
|
+
},
|
323
|
+
|
324
|
+
deleteRecord: function() {
|
325
|
+
return this.constructor.adapter.deleteRecord(this);
|
326
|
+
},
|
327
|
+
|
328
|
+
didDeleteRecord: function() {
|
329
|
+
this.constructor.removeFromRecordArrays(this);
|
330
|
+
set(this, 'isDeleted', true);
|
331
|
+
this.trigger('didDeleteRecord');
|
332
|
+
},
|
333
|
+
|
334
|
+
_copyDirtyAttributesToData: function() {
|
335
|
+
if (!this._dirtyAttributes) { return; }
|
336
|
+
var dirtyAttributes = this._dirtyAttributes,
|
337
|
+
data = get(this, 'data'),
|
338
|
+
key;
|
339
|
+
|
340
|
+
if (!data) {
|
341
|
+
data = {};
|
342
|
+
set(this, 'data', data);
|
343
|
+
}
|
344
|
+
for (var i = 0, l = dirtyAttributes.length; i < l; i++) {
|
345
|
+
// TODO: merge Object.create'd object into prototype
|
346
|
+
key = dirtyAttributes[i];
|
347
|
+
data[key] = this.cacheFor(key);
|
348
|
+
}
|
349
|
+
this._dirtyAttributes = [];
|
350
|
+
}
|
351
|
+
});
|
352
|
+
|
353
|
+
Ember.Model.reopenClass({
|
354
|
+
adapter: Ember.Adapter.create(),
|
355
|
+
|
356
|
+
find: function(id) {
|
357
|
+
if (!arguments.length) {
|
358
|
+
return this.findAll();
|
359
|
+
} else if (Ember.isArray(id)) {
|
360
|
+
return this.findMany(id);
|
361
|
+
} else if (typeof id === 'object') {
|
362
|
+
return this.findQuery(id);
|
363
|
+
} else {
|
364
|
+
return this.findById(id);
|
365
|
+
}
|
366
|
+
},
|
367
|
+
|
368
|
+
findMany: function(ids) {
|
369
|
+
Ember.assert("findMany requires an array", Ember.isArray(ids));
|
370
|
+
|
371
|
+
var records = Ember.RecordArray.create({_ids: ids});
|
372
|
+
|
373
|
+
if (!this.recordArrays) { this.recordArrays = []; }
|
374
|
+
this.recordArrays.push(records);
|
375
|
+
|
376
|
+
if (this._currentBatchIds) {
|
377
|
+
concatUnique(this._currentBatchIds, ids);
|
378
|
+
this._currentBatchRecordArrays.push(records);
|
379
|
+
} else {
|
380
|
+
this._currentBatchIds = concatUnique([], ids);
|
381
|
+
this._currentBatchRecordArrays = [records];
|
382
|
+
}
|
383
|
+
|
384
|
+
Ember.run.scheduleOnce('data', this, this._executeBatch);
|
385
|
+
|
386
|
+
return records;
|
387
|
+
},
|
388
|
+
|
389
|
+
findAll: function() {
|
390
|
+
if (this._findAllRecordArray) { return this._findAllRecordArray; }
|
391
|
+
|
392
|
+
var records = this._findAllRecordArray = Ember.RecordArray.create();
|
393
|
+
|
394
|
+
this.adapter.findAll(this, records);
|
395
|
+
|
396
|
+
return records;
|
397
|
+
},
|
398
|
+
|
399
|
+
_currentBatchIds: null,
|
400
|
+
_currentBatchRecordArrays: null,
|
401
|
+
|
402
|
+
findById: function(id) {
|
403
|
+
var record = this.cachedRecordForId(id),
|
404
|
+
adapter = get(this, 'adapter');
|
405
|
+
|
406
|
+
if (!get(record, 'isLoaded')) {
|
407
|
+
if (adapter.findMany) {
|
408
|
+
if (this._currentBatchIds) {
|
409
|
+
if (!contains(this._currentBatchIds, id)) { this._currentBatchIds.push(id); }
|
410
|
+
} else {
|
411
|
+
this._currentBatchIds = [id];
|
412
|
+
this._currentBatchRecordArrays = [];
|
413
|
+
}
|
414
|
+
|
415
|
+
Ember.run.scheduleOnce('data', this, this._executeBatch);
|
416
|
+
} else {
|
417
|
+
adapter.find(record, id);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
return record;
|
421
|
+
},
|
422
|
+
|
423
|
+
_executeBatch: function() {
|
424
|
+
var batchIds = this._currentBatchIds,
|
425
|
+
batchRecordArrays = this._currentBatchRecordArrays,
|
426
|
+
self = this,
|
427
|
+
records;
|
428
|
+
|
429
|
+
this._currentBatchIds = null;
|
430
|
+
this._currentBatchRecordArrays = null;
|
431
|
+
|
432
|
+
if (batchIds.length === 1) {
|
433
|
+
get(this, 'adapter').find(this.cachedRecordForId(batchIds[0]), batchIds[0]);
|
434
|
+
} else {
|
435
|
+
records = Ember.RecordArray.create({_ids: batchIds}),
|
436
|
+
get(this, 'adapter').findMany(this, records, batchIds);
|
437
|
+
records.then(function() {
|
438
|
+
for (var i = 0, l = batchRecordArrays.length; i < l; i++) {
|
439
|
+
batchRecordArrays[i].loadForFindMany(self);
|
440
|
+
}
|
441
|
+
});
|
442
|
+
}
|
443
|
+
},
|
444
|
+
|
445
|
+
findQuery: function(params) {
|
446
|
+
var records = Ember.RecordArray.create();
|
447
|
+
|
448
|
+
this.adapter.findQuery(this, records, params);
|
449
|
+
|
450
|
+
return records;
|
451
|
+
},
|
452
|
+
|
453
|
+
cachedRecordForId: function(id) {
|
454
|
+
if (!this.recordCache) { this.recordCache = {}; }
|
455
|
+
var sideloadedData = this.sideloadedData && this.sideloadedData[id];
|
456
|
+
var record = this.recordCache[id] || (sideloadedData ? this.create(sideloadedData) : this.create({isLoaded: false}));
|
457
|
+
if (!this.recordCache[id]) { this.recordCache[id] = record; }
|
458
|
+
return record;
|
459
|
+
},
|
460
|
+
|
461
|
+
addToRecordArrays: function(record) {
|
462
|
+
if (this._findAllRecordArray) {
|
463
|
+
this._findAllRecordArray.pushObject(record);
|
464
|
+
}
|
465
|
+
if (this.recordArrays) {
|
466
|
+
this.recordArrays.forEach(function(recordArray) {
|
467
|
+
if (recordArray instanceof Ember.FilteredRecordArray) {
|
468
|
+
recordArray.registerObserversOnRecord(record);
|
469
|
+
recordArray.updateFilter();
|
470
|
+
} else {
|
471
|
+
recordArray.pushObject(record);
|
472
|
+
}
|
473
|
+
});
|
474
|
+
}
|
475
|
+
},
|
476
|
+
|
477
|
+
removeFromRecordArrays: function(record) {
|
478
|
+
if (this._findAllRecordArray) {
|
479
|
+
this._findAllRecordArray.removeObject(record);
|
480
|
+
}
|
481
|
+
if (this.recordArrays) {
|
482
|
+
this.recordArrays.forEach(function(recordArray) {
|
483
|
+
recordArray.removeObject(record);
|
484
|
+
});
|
485
|
+
}
|
486
|
+
},
|
487
|
+
|
488
|
+
// FIXME
|
489
|
+
findFromCacheOrLoad: function(data) {
|
490
|
+
var record = this.cachedRecordForId(data.id);
|
491
|
+
// set(record, 'data', data);
|
492
|
+
record.load(data.id, data);
|
493
|
+
return record;
|
494
|
+
},
|
495
|
+
|
496
|
+
registerRecordArray: function(recordArray) {
|
497
|
+
if (!this.recordArrays) { this.recordArrays = []; }
|
498
|
+
this.recordArrays.push(recordArray);
|
499
|
+
},
|
500
|
+
|
501
|
+
unregisterRecordArray: function(recordArray) {
|
502
|
+
if (!this.recordArrays) { return; }
|
503
|
+
Ember.A(this.recordArrays).removeObject(recordArray);
|
504
|
+
},
|
505
|
+
|
506
|
+
forEachCachedRecord: function(callback) {
|
507
|
+
if (!this.recordCache) { return Ember.A([]); }
|
508
|
+
var ids = Object.keys(this.recordCache);
|
509
|
+
ids.map(function(id) {
|
510
|
+
return this.recordCache[parseInt(id, 10)];
|
511
|
+
}, this).forEach(callback);
|
512
|
+
},
|
513
|
+
|
514
|
+
load: function(hashes) {
|
515
|
+
if (!this.sideloadedData) { this.sideloadedData = {}; }
|
516
|
+
for (var i = 0, l = hashes.length; i < l; i++) {
|
517
|
+
var hash = hashes[i];
|
518
|
+
this.sideloadedData[hash.id] = hash; // FIXME: hardcoding `id` property
|
519
|
+
}
|
520
|
+
}
|
521
|
+
});
|
522
|
+
|
523
|
+
})();
|
524
|
+
|
525
|
+
|
526
|
+
|
527
|
+
(function() {
|
528
|
+
var get = Ember.get,
|
529
|
+
set = Ember.set,
|
530
|
+
meta = Ember.meta;
|
531
|
+
|
532
|
+
Ember.attr = function(type) {
|
533
|
+
return Ember.computed(function(key, value) {
|
534
|
+
var data = get(this, 'data'),
|
535
|
+
dataValue = data && get(data, key),
|
536
|
+
beingCreated = meta(this).proto === this;
|
537
|
+
|
538
|
+
if (arguments.length === 2) {
|
539
|
+
if (beingCreated) {
|
540
|
+
if (!data) {
|
541
|
+
data = {};
|
542
|
+
set(this, 'data', data);
|
543
|
+
data[key] = value;
|
544
|
+
}
|
545
|
+
return value;
|
546
|
+
}
|
547
|
+
|
548
|
+
var isEqual;
|
549
|
+
if (type && type.isEqual) {
|
550
|
+
isEqual = type.isEqual(dataValue, value);
|
551
|
+
} else {
|
552
|
+
isEqual = dataValue === value;
|
553
|
+
}
|
554
|
+
|
555
|
+
if (!isEqual) {
|
556
|
+
if (!this._dirtyAttributes) { this._dirtyAttributes = Ember.A(); }
|
557
|
+
this._dirtyAttributes.push(key);
|
558
|
+
} else {
|
559
|
+
if (this._dirtyAttributes) { this._dirtyAttributes.removeObject(key); }
|
560
|
+
}
|
561
|
+
return value;
|
562
|
+
}
|
563
|
+
|
564
|
+
if (dataValue && typeof dataValue === 'object') {
|
565
|
+
dataValue = Ember.create(dataValue);
|
566
|
+
}
|
567
|
+
return dataValue;
|
568
|
+
}).property('data').meta({isAttribute: true, type: type});
|
569
|
+
};
|
570
|
+
|
571
|
+
})();
|
572
|
+
|
573
|
+
|
574
|
+
|
575
|
+
(function() {
|
576
|
+
var get = Ember.get;
|
577
|
+
|
578
|
+
Ember.RESTAdapter = Ember.Adapter.extend({
|
579
|
+
find: function(record, id) {
|
580
|
+
var url = this.buildURL(record.constructor, id),
|
581
|
+
self = this;
|
582
|
+
|
583
|
+
return this.ajax(url).then(function(data) {
|
584
|
+
self.didFind.call(self, record, id, data);
|
585
|
+
});
|
586
|
+
},
|
587
|
+
|
588
|
+
didFind: function(record, id, data) {
|
589
|
+
var rootKey = get(record.constructor, 'rootKey'),
|
590
|
+
dataToLoad = rootKey ? data[rootKey] : data;
|
591
|
+
|
592
|
+
Ember.run(record, record.load, id, dataToLoad);
|
593
|
+
},
|
594
|
+
|
595
|
+
findAll: function(klass, records) {
|
596
|
+
var url = this.buildURL(klass),
|
597
|
+
self = this;
|
598
|
+
|
599
|
+
return this.ajax(url).then(function(data) {
|
600
|
+
self.didFindAll.call(self, klass, records, data);
|
601
|
+
});
|
602
|
+
},
|
603
|
+
|
604
|
+
didFindAll: function(klass, records, data) {
|
605
|
+
var collectionKey = get(klass, 'collectionKey'),
|
606
|
+
dataToLoad = collectionKey ? data[collectionKey] : data;
|
607
|
+
|
608
|
+
Ember.run(records, records.load, klass, dataToLoad);
|
609
|
+
},
|
610
|
+
|
611
|
+
findQuery: function(klass, records, params) {
|
612
|
+
var url = this.buildURL(klass),
|
613
|
+
self = this;
|
614
|
+
|
615
|
+
return this.ajax(url, params).then(function(data) {
|
616
|
+
self.didFindQuery.call(self, klass, records, params, data);
|
617
|
+
});
|
618
|
+
},
|
619
|
+
|
620
|
+
didFindQuery: function(klass, records, params, data) {
|
621
|
+
var collectionKey = get(klass, 'collectionKey'),
|
622
|
+
dataToLoad = collectionKey ? data[collectionKey] : data;
|
623
|
+
|
624
|
+
Ember.run(records, records.load, klass, dataToLoad);
|
625
|
+
},
|
626
|
+
|
627
|
+
createRecord: function(record) {
|
628
|
+
var url = this.buildURL(record.constructor),
|
629
|
+
self = this;
|
630
|
+
|
631
|
+
return this.ajax(url, record.toJSON(), "POST").then(function(data) {
|
632
|
+
self.didCreateRecord.call(self, record, data);
|
633
|
+
});
|
634
|
+
},
|
635
|
+
|
636
|
+
didCreateRecord: function(record, data) {
|
637
|
+
Ember.run(function() {
|
638
|
+
record.load(data.id, data); // FIXME: hardcoded ID
|
639
|
+
record.didCreateRecord();
|
640
|
+
});
|
641
|
+
},
|
642
|
+
|
643
|
+
saveRecord: function(record) {
|
644
|
+
var url = this.buildURL(record.constructor, get(record, 'id')),
|
645
|
+
self = this;
|
646
|
+
|
647
|
+
return this.ajax(url, record.toJSON(), "PUT").then(function(data) { // TODO: Some APIs may or may not return data
|
648
|
+
self.didSaveRecord.call(self, record, data);
|
649
|
+
});
|
650
|
+
},
|
651
|
+
|
652
|
+
didSaveRecord: function(record, data) {
|
653
|
+
Ember.run(record, record.didSaveRecord);
|
654
|
+
},
|
655
|
+
|
656
|
+
deleteRecord: function(record) {
|
657
|
+
var url = this.buildURL(record.constructor, get(record, 'id')),
|
658
|
+
self = this;
|
659
|
+
|
660
|
+
return this.ajax(url, record.toJSON(), "DELETE").then(function(data) { // TODO: Some APIs may or may not return data
|
661
|
+
self.didDeleteRecord.call(self, record, data);
|
662
|
+
});
|
663
|
+
},
|
664
|
+
|
665
|
+
didDeleteRecord: function(record, data) {
|
666
|
+
Ember.run(record, record.didDeleteRecord);
|
667
|
+
},
|
668
|
+
|
669
|
+
ajax: function(url, params, method) {
|
670
|
+
return this._ajax(url, params, method || "GET");
|
671
|
+
},
|
672
|
+
|
673
|
+
buildURL: function(klass, id) {
|
674
|
+
var urlRoot = get(klass, 'url');
|
675
|
+
if (!urlRoot) { throw new Error('Ember.RESTAdapter requires a `url` property to be specified'); }
|
676
|
+
|
677
|
+
if (id) {
|
678
|
+
return urlRoot + "/" + id + ".json";
|
679
|
+
} else {
|
680
|
+
return urlRoot + ".json";
|
681
|
+
}
|
682
|
+
},
|
683
|
+
|
684
|
+
_ajax: function(url, params, method) {
|
685
|
+
var settings = {
|
686
|
+
url: url,
|
687
|
+
type: method,
|
688
|
+
dataType: "json"
|
689
|
+
};
|
690
|
+
|
691
|
+
if (params && method !== "GET") {
|
692
|
+
settings.contentType = "application/json; charset=utf-8";
|
693
|
+
settings.data = JSON.stringify(params);
|
694
|
+
}
|
695
|
+
|
696
|
+
return Ember.$.ajax(settings);
|
697
|
+
}
|
698
|
+
});
|
699
|
+
|
700
|
+
})();
|
701
|
+
|
702
|
+
|
703
|
+
|
704
|
+
(function() {
|
705
|
+
|
706
|
+
})();
|
707
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: Ember Data
|
3
|
+
// Copyright: ©2011-2012 Tilde Inc. and contributors.
|
4
|
+
// Portions ©2011 Living Social Inc. and contributors.
|
5
|
+
// License: Licensed under MIT license (see license.js)
|
6
|
+
// ==========================================================================
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
// Last commit: 7656e63 (2013-05-28 17:06:31 -0700)
|
11
|
+
|
12
|
+
|
13
|
+
(function(){Ember.Adapter=Ember.Object.extend({find:function(){throw new Error("Ember.Adapter subclasses must implement find")},findQuery:function(){throw new Error("Ember.Adapter subclasses must implement findQuery")},findMany:function(){throw new Error("Ember.Adapter subclasses must implement findMany")},findAll:function(){throw new Error("Ember.Adapter subclasses must implement findAll")},load:function(r,e,t){r.load(e,t)},createRecord:function(){throw new Error("Ember.Adapter subclasses must implement createRecord")},saveRecord:function(){throw new Error("Ember.Adapter subclasses must implement saveRecord")},deleteRecord:function(){throw new Error("Ember.Adapter subclasses must implement deleteRecord")}})})(),function(){Ember.FixtureAdapter=Ember.Adapter.extend({find:function(r,e){var t=r.constructor.FIXTURES,i=Ember.A(t).find(function(r){return r.id===e});r.get("isLoaded")||setTimeout(function(){Ember.run(r,r.load,e,i)})},findMany:function(r,e,t){for(var i=r.FIXTURES,n=[],o=0,d=t.length;d>o;o++)n.push(i[o]);setTimeout(function(){Ember.run(e,e.load,r,n)})},findAll:function(r,e){var t=r.FIXTURES;setTimeout(function(){Ember.run(e,e.load,r,t)})},createRecord:function(r){var e=r.constructor,t=e.FIXTURES;return setTimeout(function(){Ember.run(function(){t.push(e.findFromCacheOrLoad(r.toJSON())),r.didCreateRecord()})}),r},saveRecord:function(r){var e=Ember.Deferred.create();return e.then(function(){r.didSaveRecord()}),setTimeout(function(){Ember.run(e,e.resolve,r)}),e},deleteRecord:function(r){var e=Ember.Deferred.create();return e.then(function(){r.didDeleteRecord()}),setTimeout(function(){Ember.run(e,e.resolve,r)}),e}})}(),function(){var r=Ember.get,e=Ember.set;Ember.RecordArray=Ember.ArrayProxy.extend(Ember.Evented,Ember.DeferredMixin,{isLoaded:!1,isLoading:Ember.computed.not("isLoaded"),load:function(r,t){e(this,"content",this.materializeData(r,t)),this.notifyLoaded()},loadForFindMany:function(t){var i=r(this,"_ids").map(function(r){return t.cachedRecordForId(r)});e(this,"content",Ember.A(i)),this.notifyLoaded()},notifyLoaded:function(){e(this,"isLoaded",!0),this.trigger("didLoad"),this.resolve(this)},materializeData:function(r,e){return Ember.A(e.map(function(e){return r.findFromCacheOrLoad(e)}))}})}(),function(){var r=Ember.get;Ember.FilteredRecordArray=Ember.RecordArray.extend({init:function(){if(!r(this,"modelClass"))throw new Error("FilteredRecordArrays must be created with a modelClass");if(!r(this,"filterFunction"))throw new Error("FilteredRecordArrays must be created with a filterFunction");if(!r(this,"filterProperties"))throw new Error("FilteredRecordArrays must be created with filterProperties");var e=r(this,"modelClass");e.registerRecordArray(this),this.registerObservers(),this.updateFilter()},updateFilter:function(){var e=this,t=[];r(this,"modelClass").forEachCachedRecord(function(r){e.filterFunction(r)&&t.push(r)}),this.set("content",Ember.A(t))},updateFilterForRecord:function(e){var t=r(this,"content");this.filterFunction(e)&&t.pushObject(e)},registerObservers:function(){var e=this;r(this,"modelClass").forEachCachedRecord(function(r){e.registerObserversOnRecord(r)})},registerObserversOnRecord:function(e){for(var t=this,i=r(this,"filterProperties"),n=0,o=r(i,"length");o>n;n++)e.addObserver(i[n],t,"updateFilterForRecord")}})}(),function(){function r(r,e){for(var t=0,i=r.length;i>t;t++)if(r[t]===e)return!0;return!1}function e(e,t){for(var i,n=0,o=t.length;o>n;n++)i=t[n],r(e,i)||e.push(i);return e}var t=Ember.get,i=Ember.set,n=Ember.meta;Ember.run.queues.push("data"),Ember.Model=Ember.Object.extend(Ember.Evented,Ember.DeferredMixin,{isLoaded:!0,isLoading:Ember.computed.not("isLoaded"),isNew:!0,isDeleted:!1,_dirtyAttributes:null,isDirty:Ember.computed(function(){for(var r,e,i,o,d,s,a,c=this.attributes,u=this._dirtyAttributes,h=0,f=c.length;f>h;h++)r=c[h],e=this.cacheFor(r),i=t(this,"data."+r),o=n(this).descs[r],d=o&&o.meta(),s=d.type,a=u&&-1!==u.indexOf(r),!a&&s&&s.isEqual&&(s.isEqual(i,e||i)||(u||(u=this._dirtyAttributes=Ember.A()),u.push(r)));return u&&0!==u.length}).property().volatile(),init:function(){t(this,"isNew")||this.resolve(this),this._super()},load:function(r,e){var t=Ember.merge({id:r},e);i(this,"data",t),i(this,"isLoaded",!0),i(this,"isNew",!1),this.trigger("didLoad"),this.resolve(this)},didDefineProperty:function(r,e,t){if(t instanceof Ember.Descriptor){var i=t.meta();i.isAttribute&&(r.attributes||(r.attributes=[]),r.attributes.push(e))}},toJSON:function(){return this.getProperties(this.attributes)},save:function(){var r=this.constructor.adapter;if(i(this,"isSaving",!0),t(this,"isNew"))return r.createRecord(this);if(t(this,"isDirty"))return r.saveRecord(this);var e=Ember.Deferred.create();return e.resolve(this),e},didCreateRecord:function(){i(this,"isNew",!1),this.load(this.get("id"),this.getProperties(this.attributes)),this.constructor.addToRecordArrays(this),this.trigger("didCreateRecord"),this.didSaveRecord()},didSaveRecord:function(){i(this,"isSaving",!1),this.trigger("didSaveRecord"),this._copyDirtyAttributesToData()},deleteRecord:function(){return this.constructor.adapter.deleteRecord(this)},didDeleteRecord:function(){this.constructor.removeFromRecordArrays(this),i(this,"isDeleted",!0),this.trigger("didDeleteRecord")},_copyDirtyAttributesToData:function(){if(this._dirtyAttributes){var r,e=this._dirtyAttributes,n=t(this,"data");n||(n={},i(this,"data",n));for(var o=0,d=e.length;d>o;o++)r=e[o],n[r]=this.cacheFor(r);this._dirtyAttributes=[]}}}),Ember.Model.reopenClass({adapter:Ember.Adapter.create(),find:function(r){return arguments.length?Ember.isArray(r)?this.findMany(r):"object"==typeof r?this.findQuery(r):this.findById(r):this.findAll()},findMany:function(r){var t=Ember.RecordArray.create({_ids:r});return this.recordArrays||(this.recordArrays=[]),this.recordArrays.push(t),this._currentBatchIds?(e(this._currentBatchIds,r),this._currentBatchRecordArrays.push(t)):(this._currentBatchIds=e([],r),this._currentBatchRecordArrays=[t]),Ember.run.scheduleOnce("data",this,this._executeBatch),t},findAll:function(){if(this._findAllRecordArray)return this._findAllRecordArray;var r=this._findAllRecordArray=Ember.RecordArray.create();return this.adapter.findAll(this,r),r},_currentBatchIds:null,_currentBatchRecordArrays:null,findById:function(e){var i=this.cachedRecordForId(e),n=t(this,"adapter");return t(i,"isLoaded")||(n.findMany?(this._currentBatchIds?r(this._currentBatchIds,e)||this._currentBatchIds.push(e):(this._currentBatchIds=[e],this._currentBatchRecordArrays=[]),Ember.run.scheduleOnce("data",this,this._executeBatch)):n.find(i,e)),i},_executeBatch:function(){var r,e=this._currentBatchIds,i=this._currentBatchRecordArrays,n=this;this._currentBatchIds=null,this._currentBatchRecordArrays=null,1===e.length?t(this,"adapter").find(this.cachedRecordForId(e[0]),e[0]):(r=Ember.RecordArray.create({_ids:e}),t(this,"adapter").findMany(this,r,e),r.then(function(){for(var r=0,e=i.length;e>r;r++)i[r].loadForFindMany(n)}))},findQuery:function(r){var e=Ember.RecordArray.create();return this.adapter.findQuery(this,e,r),e},cachedRecordForId:function(r){this.recordCache||(this.recordCache={});var e=this.sideloadedData&&this.sideloadedData[r],t=this.recordCache[r]||(e?this.create(e):this.create({isLoaded:!1}));return this.recordCache[r]||(this.recordCache[r]=t),t},addToRecordArrays:function(r){this._findAllRecordArray&&this._findAllRecordArray.pushObject(r),this.recordArrays&&this.recordArrays.forEach(function(e){e instanceof Ember.FilteredRecordArray?(e.registerObserversOnRecord(r),e.updateFilter()):e.pushObject(r)})},removeFromRecordArrays:function(r){this._findAllRecordArray&&this._findAllRecordArray.removeObject(r),this.recordArrays&&this.recordArrays.forEach(function(e){e.removeObject(r)})},findFromCacheOrLoad:function(r){var e=this.cachedRecordForId(r.id);return e.load(r.id,r),e},registerRecordArray:function(r){this.recordArrays||(this.recordArrays=[]),this.recordArrays.push(r)},unregisterRecordArray:function(r){this.recordArrays&&Ember.A(this.recordArrays).removeObject(r)},forEachCachedRecord:function(r){if(!this.recordCache)return Ember.A([]);var e=Object.keys(this.recordCache);e.map(function(r){return this.recordCache[parseInt(r,10)]},this).forEach(r)},load:function(r){this.sideloadedData||(this.sideloadedData={});for(var e=0,t=r.length;t>e;e++){var i=r[e];this.sideloadedData[i.id]=i}}})}(),function(){var r=Ember.get,e=Ember.set,t=Ember.meta;Ember.attr=function(i){return Ember.computed(function(n,o){var d=r(this,"data"),s=d&&r(d,n),a=t(this).proto===this;if(2===arguments.length){if(a)return d||(d={},e(this,"data",d),d[n]=o),o;var c;return c=i&&i.isEqual?i.isEqual(s,o):s===o,c?this._dirtyAttributes&&this._dirtyAttributes.removeObject(n):(this._dirtyAttributes||(this._dirtyAttributes=Ember.A()),this._dirtyAttributes.push(n)),o}return s&&"object"==typeof s&&(s=Ember.create(s)),s}).property("data").meta({isAttribute:!0,type:i})}}(),function(){var r=Ember.get;Ember.RESTAdapter=Ember.Adapter.extend({find:function(r,e){var t=this.buildURL(r.constructor,e),i=this;return this.ajax(t).then(function(t){i.didFind.call(i,r,e,t)})},didFind:function(e,t,i){var n=r(e.constructor,"rootKey"),o=n?i[n]:i;Ember.run(e,e.load,t,o)},findAll:function(r,e){var t=this.buildURL(r),i=this;return this.ajax(t).then(function(t){i.didFindAll.call(i,r,e,t)})},didFindAll:function(e,t,i){var n=r(e,"collectionKey"),o=n?i[n]:i;Ember.run(t,t.load,e,o)},findQuery:function(r,e,t){var i=this.buildURL(r),n=this;return this.ajax(i,t).then(function(i){n.didFindQuery.call(n,r,e,t,i)})},didFindQuery:function(e,t,i,n){var o=r(e,"collectionKey"),d=o?n[o]:n;Ember.run(t,t.load,e,d)},createRecord:function(r){var e=this.buildURL(r.constructor),t=this;return this.ajax(e,r.toJSON(),"POST").then(function(e){t.didCreateRecord.call(t,r,e)})},didCreateRecord:function(r,e){Ember.run(function(){r.load(e.id,e),r.didCreateRecord()})},saveRecord:function(e){var t=this.buildURL(e.constructor,r(e,"id")),i=this;return this.ajax(t,e.toJSON(),"PUT").then(function(r){i.didSaveRecord.call(i,e,r)})},didSaveRecord:function(r){Ember.run(r,r.didSaveRecord)},deleteRecord:function(e){var t=this.buildURL(e.constructor,r(e,"id")),i=this;return this.ajax(t,e.toJSON(),"DELETE").then(function(r){i.didDeleteRecord.call(i,e,r)})},didDeleteRecord:function(r){Ember.run(r,r.didDeleteRecord)},ajax:function(r,e,t){return this._ajax(r,e,t||"GET")},buildURL:function(e,t){var i=r(e,"url");if(!i)throw new Error("Ember.RESTAdapter requires a `url` property to be specified");return t?i+"/"+t+".json":i+".json"},_ajax:function(r,e,t){var i={url:r,type:t,dataType:"json"};return e&&"GET"!==t&&(i.contentType="application/json; charset=utf-8",i.data=JSON.stringify(e)),Ember.$.ajax(i)}})}(),"undefined"==typeof location||"localhost"!==location.hostname&&"127.0.0.1"!==location.hostname||console.warn("You are running a production build of Ember on localhost and won't receive detailed error messages. If you want full error messages please use the non-minified build provided on the Ember website.");
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ember-model-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 73
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
- 1
|
11
|
+
version: 0.0.1.1
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- Alex Auritt
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2013-06-01 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: railties
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 5
|
30
|
+
segments:
|
31
|
+
- 3
|
32
|
+
- 1
|
33
|
+
version: "3.1"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: put the models...
|
37
|
+
email:
|
38
|
+
- alexauritt@yahoo.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- lib/ember-model-rails/version.rb
|
47
|
+
- lib/ember-model-rails.rb
|
48
|
+
- vendor/assets/javascripts/ember-model.js
|
49
|
+
- vendor/assets/javascripts/ember-model.min.js
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
homepage: ""
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.8.24
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: ... in the pipeline
|
85
|
+
test_files: []
|
86
|
+
|