Ember no consigue obtener cierto atributo.

Al ejecutar lo siguiente desde el UserController en Google Chrome, con ember-couchdb-kit-0.9 , Ember Data v1.0.0-beta.3-56-g8367aa5 , Ember v1.0.0 , y este adaptador couchdb :

 customerSignUp: function () { var model = this.get('model'); var customer = this.get('store').createRecord('customer', { description: 'Why hello sir', user: model }); customer.save().then(function() { model.set('customer', customer); model.save(); }); } 

con estos modelos:

 App.User = App.Person.extend({ name: DS.attr('string'), customer: DS.belongsTo('customer', {async: true }) App.Customer = DS.Model.extend({ user: DS.belongsTo('user', {async: true}), description: DS.attr('string') }); 

ni el usuario ni el cliente tienen su relación establecida correctamente (en el Depurador de Ember, el usuario tiene un null y el cliente tiene , en lugar de algún tipo de que es lo que tienen cuando funciona). Esto solo ocurre cuando el objeto en cuestión persiste. Si se omiten las llamadas a save() , ambas tienen relaciones establecidas correctamente, pero por supuesto la base de datos no se ha actualizado con esta información. Cuando suceden las salvaciones, las relaciones se sobrescriben con entradas vacías.

Encontré que el problema estaba en la función serializeBelongsTo del adaptador, que ahora he cambiado mi copia a lo siguiente:

 serializeBelongsTo: function(record, json, relationship) { console.log("serializeBelongsTo"); console.log(record.get('user')); console.log(json); console.log(relationship); var attribute, belongsTo, key; attribute = relationship.options.attribute || "id"; console.log(attribute); key = relationship.key; console.log(key); belongsTo = Ember.get(record, key); console.log(belongsTo); if (Ember.isNone(belongsTo)) { return; } json[key] = Ember.get(belongsTo, attribute); console.log(Ember.get(belongsTo, attribute)); console.log(json); if (relationship.options.polymorphic) { return json[key + "_type"] = belongsTo.constructor.typeKey; } else { return json; } } 

attribute , belongsTo , y key todos los registros como correctos, pero console.log(Ember.get(belongsTo, attribute)); devuelve undefined , que he intentado cambiar a console.log(Ember.get(Ember.get(belongsTo, 'content'), attribute)); desde console.log(belongsTo); me dijo que el atributo id estaba oculto dentro de un objeto de content . Se adjunta una captura de pantalla que muestra lo que quiero decir. captura de pantalla del 2013-12-07 18 15 52 Sin embargo, el cambio no soluciona el problema, y ​​sigo undefined . belongsTo método que use para intentar obtener el ID del objeto belongsTo , siempre obtengo un null o undefined . Aquí hay algunos ejemplos de cosas que he tratado de sacar content del objeto:

 var content = belongsTo.content; var content = Ember.get(belongsTo, 'content'); var content = belongsTo.get('content'); 

console.log(json); devuelve el Object {description: "Why hello sir", user: undefined}

Aquí hay un pastebin que muestra resultados relevantes: http://pastebin.com/v4mb3PJ2

Actualizar

Una actualización muy confusa!

Cuando guardo el modelo desde una función diferente:

 saveModel: function() { this.get('model').save().then( function( data, textStatus, jqXHR ) { console.log('Saved successfully.'); }, function( jqXHR, textStatus, errorThrown ) { console.log(jqXHR); console.log(errorThrown); console.log(textStatus); } ); } 

El modelo está correctamente guardado. Todo en serializeBelongsto funciona exactamente como se esperaba.

Aquí hay un pastebin diferente que muestra el resultado para este caso: http://pastebin.com/Vawur8Q0

Resolví el problema. Básicamente, el objeto belongsTo en serializeBelongsTo no se resolvió realmente en el momento en que se hizo referencia, lo cual descubrí al consultar isFulfilled . Así lo implementé guardando lado de esta manera:

 function saveOn (target, attribute) { target.addObserver(attribute, function () { if (target.get(attribute)) { console.log("Inside with %@".fmt(attribute)); target.removeObserver(attribute); Ember.run.once(target, function() { target.save(); }); } }); }; customerSignUp: function () { var model = this.get('model'); var customer = this.get('store').createRecord('customer', { description: 'Why hello sir' }); customer.save().then(function () { model.set('customer', customer); customer.set('user', model); saveOn(customer, 'user.isFulfilled'); saveOn(model, 'customer.isFulfilled'); }); } 

Ahora todo funciona como un amuleto. Sin embargo, podría ser una buena idea que serializeBelongsTo tenga esto en cuenta. Esta línea: console.log(Ember.get(belongsTo, 'isFulfilled')); Estaba saliendo false en mi caso. ¡Solo hubo una condición de carrera de algún tipo entre la creación del registro y su serialización!

Sin embargo, me gustaría hacer que mi función saveOn devuelva una promesa, que luego podría usar para encadenar varios saveOn s juntos. De esa manera no tendría que hacer un customer.save() para asegurarme de que los ID se rellenaron.