2

I'm working with a set of data that can potentially have duplicate values. When I initially add the data I'm using what little information I have available on the client (static info stored on the model in memory).

But because I need to fetch the latest each time the handlebars template is shown I also fire off a "findAll" in the computed property to get any new data that might have hit server side since the initial ember app was launched.

During this process I use the "addObjects" method on the ember-data model but when the server side is returned I see duplicate records in the array (assuming it's because they don't have the same clientId)

App.Day = DS.Model.extend({
    appointments: function() {
        //this will hit a backend server so it's slow
        return App.Appointment.find();
    }.property(),
    slots: function() {
        //no need to hit a backend server here so it's fast
        return App.Slot.all();
    }.property(),
    combined: function() {
        var apts = this.get('apppointments'),
        slots = this.get('slots');
        for(var i = 0; i < slots.get('length'); i++) {
          var slot = slots.objectAt(i);
          var tempApt = App.Appointment.createRecord({start: slot.get('start'), end: slot.get('end')});
          apts.addObjects(tempApt);
        }            

        return apts;
    }.property()
});

Is it possible to tell an ember-data model what makes it unique so that when the promise is resolved it will know "this already exists in the AdapterPopulatedRecordArray so I'll just update it's value instead of showing it twice"

Toran Billups
  • 27,111
  • 40
  • 155
  • 268

1 Answers1

2

You can use

DS.RESTAdapter.map('App.Slot', {
  primaryKey: 'name-of-attribute'
});
DS.RESTAdapter.map('App.Appointment', {
  primaryKey: 'name-of-attribute'
});

But I think it is still impossible because App.Slot and App.Appointment are different model classes, so if they have same ids it won't help. You need to use the same model for both slots and appointments for this to work.

Edit

After examinig the source of ember-data, i think that you can define the primaryKey when you define your classes, like:

App.Slot = DS.Model.extend({
    primaryKey: 'myId',
    otherField: DS.attr('number')
});

I didn't tested it though..

Edit 2

After further reading seems that the previous edit is no longer supported. You need to use map as i wrote earlier.

Shimon Rachlenko
  • 5,469
  • 40
  • 51
  • I just updated the code above -i actually create an "empty" appointment per slot now (so it's just 1 model). This way the appointment I'm adding is just a placeholder of sorts -if that time slot is empty on the server side (no harm it remains empty) .. but if it's got an appointment already in that slot (server side) I need to update the item based on start/end values (is that possible or is the primaryKey idea a single field?) – Toran Billups Feb 07 '13 at 13:48
  • Now you can use the `primaryKey` mapping to define the custom id, but from the source code it seems that it is a single field. I think you need to write your own adapter, or, maybe, a serializer(less work). – Shimon Rachlenko Feb 07 '13 at 14:10
  • You may get away with creating a custom field which is a combination of start/end in a one-one correspondence way, and use that field as id. Something like _start-X-end_ may go.. – Shimon Rachlenko Feb 07 '13 at 14:13
  • If I create an item with a PK that might exist after the ajax call ember-data blows up internally (seemingly it doesn't like this approach -loading a record after the pk is already in the object graph). Have you had any luck doing this or ? – Toran Billups Feb 10 '13 at 19:33