Skip to content
This repository
Browse code

Add record.reload()

  • Loading branch information...
commit 278a0b863f0b1b2494fe2319ac12be6167195f6b 1 parent 508479d
Yehuda Katz wycats authored
6 packages/ember-data/lib/serializers/json_serializer.js
@@ -225,8 +225,12 @@ DS.JSONSerializer = DS.Serializer.extend({
225 225 },
226 226
227 227 rootForType: function(type) {
  228 + var typeString = type.toString();
  229 +
  230 + Ember.assert("Your model must not be anonymous. It was " + type, typeString.charAt(0) !== '(');
  231 +
228 232 // use the last part of the name as the URL
229   - var parts = type.toString().split(".");
  233 + var parts = typeString.split(".");
230 234 var name = parts[parts.length - 1];
231 235 return name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
232 236 }
13 packages/ember-data/lib/system/model/model.js
@@ -11,6 +11,7 @@ var retrieveFromCurrentState = Ember.computed(function(key) {
11 11
12 12 DS.Model = Ember.Object.extend(Ember.Evented, LoadPromise, {
13 13 isLoaded: retrieveFromCurrentState,
  14 + isReloading: retrieveFromCurrentState,
14 15 isDirty: retrieveFromCurrentState,
15 16 isSaving: retrieveFromCurrentState,
16 17 isDeleted: retrieveFromCurrentState,
@@ -42,6 +43,7 @@ DS.Model = Ember.Object.extend(Ember.Evented, LoadPromise, {
42 43 },
43 44
44 45 didLoad: Ember.K,
  46 + didReload: Ember.K,
45 47 didUpdate: Ember.K,
46 48 didCreate: Ember.K,
47 49 didDelete: Ember.K,
@@ -109,6 +111,17 @@ DS.Model = Ember.Object.extend(Ember.Evented, LoadPromise, {
109 111 this.send('setProperty', { key: key, value: value, oldValue: oldValue });
110 112 },
111 113
  114 + /**
  115 + Reload the record from the adapter.
  116 +
  117 + This will only work if the record has already finished loading
  118 + and has not yet been modified (`isLoaded` but not `isDirty`,
  119 + or `isSaving`).
  120 + */
  121 + reload: function() {
  122 + this.send('reloadRecord');
  123 + },
  124 +
112 125 deleteRecord: function() {
113 126 this.send('deleteRecord');
114 127 },
34 packages/ember-data/lib/system/model/states.js
... ... @@ -1,5 +1,5 @@
1 1 var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor,
2   - arrayMap = Ember.ArrayPolyfills.map;
  2 + once = Ember.run.once, arrayMap = Ember.ArrayPolyfills.map;
3 3
4 4 /**
5 5 This file encapsulates the various states that a record can transition
@@ -201,6 +201,7 @@ var updateRecordArrays = function(manager) {
201 201
202 202 DS.State = Ember.State.extend({
203 203 isLoaded: stateProperty,
  204 + isReloading: stateProperty,
204 205 isDirty: stateProperty,
205 206 isSaving: stateProperty,
206 207 isDeleted: stateProperty,
@@ -471,6 +472,7 @@ var states = {
471 472 rootState: Ember.State.create({
472 473 // FLAGS
473 474 isLoaded: false,
  475 + isReloading: false,
474 476 isDirty: false,
475 477 isSaving: false,
476 478 isDeleted: false,
@@ -548,6 +550,32 @@ var states = {
548 550 })
549 551 }),
550 552
  553 + reloading: DS.State.create({
  554 + // FLAGS
  555 + isReloading: true,
  556 +
  557 + // TRANSITIONS
  558 + enter: function(manager) {
  559 + var record = get(manager, 'record'),
  560 + store = get(record, 'store');
  561 +
  562 + store.reloadRecord(record);
  563 + },
  564 +
  565 + exit: function(manager) {
  566 + var record = get(manager, 'record');
  567 +
  568 + once(record, 'trigger', 'didReload');
  569 + },
  570 +
  571 + // EVENTS
  572 + loadedData: didChangeData,
  573 +
  574 + materializingData: function(manager) {
  575 + manager.transitionTo('loaded.materializing');
  576 + }
  577 + }),
  578 +
551 579 // If there are no local changes to a record, it remains
552 580 // in the `saved` state.
553 581 saved: DS.State.create({
@@ -558,6 +586,10 @@ var states = {
558 586 didChangeData: didChangeData,
559 587 loadedData: didChangeData,
560 588
  589 + reloadRecord: function(manager) {
  590 + manager.transitionTo('loaded.reloading');
  591 + },
  592 +
561 593 materializingData: function(manager) {
562 594 manager.transitionTo('loaded.materializing');
563 595 },
12 packages/ember-data/lib/system/store.js
@@ -496,6 +496,18 @@ DS.Store = Ember.Object.extend(DS._Mappable, {
496 496 return record;
497 497 },
498 498
  499 + reloadRecord: function(record) {
  500 + var type = record.constructor,
  501 + adapter = this.adapterForType(type),
  502 + id = get(record, 'id');
  503 +
  504 + Ember.assert("You cannot update a record without an ID", id);
  505 + Ember.assert("You tried to update a record but you have no adapter (for " + type + ")", adapter);
  506 + Ember.assert("You tried to update a record but your adapter does not implement `find`", adapter.find);
  507 +
  508 + adapter.find(this, type, id);
  509 + },
  510 +
499 511 /**
500 512 @private
501 513
96 packages/ember-data/tests/integration/reload_test.js
... ... @@ -0,0 +1,96 @@
  1 +var get = Ember.get, set = Ember.set;
  2 +var Person, store, adapter;
  3 +
  4 +module("Reloading Records", {
  5 + setup: function() {
  6 + Person = DS.Model.extend({
  7 + updatedAt: DS.attr('string'),
  8 + name: DS.attr('string'),
  9 + firstName: DS.attr('string'),
  10 + lastName: DS.attr('string')
  11 + });
  12 +
  13 + Person.toString = function() { return "Person"; };
  14 +
  15 + adapter = DS.Adapter.create();
  16 + store = DS.Store.create({ adapter: adapter });
  17 + },
  18 +
  19 + teardown: function() {
  20 + adapter.destroy();
  21 + store.destroy();
  22 + }
  23 +});
  24 +
  25 +asyncTest("When a single record is requested, the adapter's find method should be called unless it's loaded.", function() {
  26 + expect(5);
  27 +
  28 + var count = 0;
  29 +
  30 + adapter.find = function(store, type, id) {
  31 + if (count === 0) {
  32 + setTimeout(function() {
  33 + adapter.didFindRecord(store, type, { person: { name: "Tom Dale" } }, id);
  34 + firstFound();
  35 + });
  36 + count++;
  37 + } else if (count === 1) {
  38 + setTimeout(function() {
  39 + adapter.didFindRecord(store, type, { person: { name: "Braaaahm Dale" } }, id);
  40 + secondFound();
  41 + });
  42 + count++;
  43 + } else {
  44 + ok(false, "Should not get here");
  45 + }
  46 + };
  47 +
  48 + var person = store.find(Person, 1);
  49 +
  50 + var waitingFor = 2;
  51 +
  52 + function done() {
  53 + if (--waitingFor === 0) { start(); }
  54 + }
  55 +
  56 + function firstFound() {
  57 + equal(get(person, 'name'), "Tom Dale", "The person is loaded with the right name");
  58 + equal(get(person, 'isLoaded'), true, "The person is now loaded");
  59 + person.one('didReload', done);
  60 + person.reload();
  61 + equal(get(person, 'isReloading'), true, "The person is now reloading");
  62 + }
  63 +
  64 + function secondFound() {
  65 + done();
  66 + equal(get(person, 'isReloading'), false, "The person is no longer reloading");
  67 + equal(get(person, 'name'), "Braaaahm Dale", "The person is now updated with the right name");
  68 + }
  69 +});
  70 +
  71 +asyncTest("If a record is modified, it cannot be reloaded", function() {
  72 + var count = 0;
  73 +
  74 + adapter.find = function(store, type, id) {
  75 + if (count === 0) {
  76 + setTimeout(function() {
  77 + adapter.didFindRecord(store, type, { person: { name: "Tom Dale" } }, id);
  78 + found();
  79 + });
  80 + count++;
  81 + } else {
  82 + ok(false, "Should not get here");
  83 + }
  84 + };
  85 +
  86 + var person = store.find(Person, 1);
  87 +
  88 + function found() {
  89 + start();
  90 + set(person, 'name', "Braaaaahm Dale");
  91 +
  92 + raises(function() {
  93 + person.reload();
  94 + }, /uncommitted/);
  95 + }
  96 +});

0 comments on commit 278a0b8

Please sign in to comment.
Something went wrong with that request. Please try again.