Ember dane zapisywanie relacji

Mam trudności z zapisaniem relacji jeden do wielu w Ember data. Mam taki związek:

App.ParameterSet = DS.Model
    name: DS.attr("string")
    regions: DS.hasMany("App.Region")

App.Region = DS.Model
    name: DS.attr("string")

Gdybym miał zrobić coś takiego:

parameterSet = App.ParameterSet.find(5)
@transaction = @get("store").transaction()
@transaction.add(parameterSet)
region1 = App.Region.find(10)
region2 = App.Region.find(11)
parameterSet.set("name", "foo")
parameterSet.get("regions").pushObject(region)
@transaction.commit()

Wtedy chciałbym zobaczyć żądanie PUT z ładunkiem takim jak:

api/ParameterSets/5

{parameterSet: {name: "foo", regionIds:[10, 11]}}

Ale zamiast tego rozumiem to:

{parameterSet: {name: "foo"}}

Nie zależy mi na relacji z dzieckiem do rodzica, ale jeśli dodam parameterSet: DS.belongsTo("App.ParameterSet") do aplikacji.Model regionu następnie dostaję 2 umieścić wnioski do regionów url dla dwóch nowych relacji, które są nie tego chcę.

Myślę, że jest to związek wielu do wielu, który nie jestem pewien, czy jest jeszcze wspierany, ale jakieś pomysły, jak osiągnąć to, co opisałem? Dzięki

Author: Charlie, 2013-02-28

2 answers

Serializacja relacji hasMany jest obsługiwana metodą addHasMany() json_serializer.js.

W kodzie źródłowym znajduje się następująca Uwaga:

Domyślną semantyką REST jest dodanie relacji has-many tylko wtedy, gdy jest osadzony. Jeśli relacja została pierwotnie załadowana przez ID, Zakładamy, że to zostało zrobione jako optymalizacja wydajności, a to zmienia się w ma-wiele należy zapisać jako zmiany klucza obcego na dziecko należy-do związek.

Aby osiągnąć to, co chcesz, jedną z opcji jest wskazanie, że relacja powinna być osadzona w Twoim adapterze.

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    serializer: DS.RESTSerializer.extend({
      init: function() {
        this._super();
        this.map('App.ParameterSet', {
          regions: { embedded: 'always' }
        });
      }
    })
  })
});

Oczywiście teraz twój back-end będzie musiał faktycznie osadzić JSON powiązanych regionów w JSON zestawu parametrów. Jeśli chcesz zachować rzeczy takie, jakie są, możesz po prostu nadpisać addHasMany() za pomocą niestandardowej serializacji.

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    serializer: DS.RESTSerializer.extend({
      addHasMany: function(hash, record, key, relationship) {
        // custom ...
      }
    })
  })
});
 8
Author: ahmacleod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 21:16:34

Nie jestem w stanie dodawać komentarzy do odpowiedzi ahmacleoda, ale jest na miejscu, z tym, że zauważyłem, że rekord rodzica nie jest oznaczony jako brudny, gdy rekord dziecka jest modyfikowany. W przykładzie w pytaniu problem nie występuje, ponieważ nazwa jest również modyfikowana w rekordie nadrzędnym.

Ogólnie rzecz biorąc, jeśli zamierzasz podążać za drugą odpowiedzią ahmacleoda, musisz nadpisać metodę dirtyRecordsForHasManyChange na Restadapterze. W przeciwnym razie dodaj do serializer nigdy nie jest wywoływany, ponieważ płyta nie jest nawet oznaczona jako brudna.

Istniejąca metoda wygląda następująco:

dirtyRecordsForHasManyChange: function(dirtySet, record, relationship) {
  var embeddedType = get(this, 'serializer').embeddedType(record.constructor, relationship.secondRecordName);

  if (embeddedType === 'always') {
    relationship.childReference.parent = relationship.parentReference;
    this._dirtyTree(dirtySet, record);
  }
},

Więc chyba będziesz chciał coś w stylu:

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.extend({
    dirtyRecordsForHasManyChange: function(dirtySet, record, relationship) {
      relationship.childReference.parent = relationship.parentReference;
      this._dirtyTree(dirtySet, record);
    },

    serializer: DS.RESTSerializer.extend({
      addHasMany: function(hash, record, key, relationship) {
        // custom ...
      }
    })
  })
});
 2
Author: meelash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-16 15:44:07