Zatvobor / ember-couchdb-kit

An Ember.js adapter for Apache CouchDB
MIT License
43 stars 13 forks source link

serializeBelongsTo saves relationship to undefined. #87

Closed blainehansen closed 4 years ago

blainehansen commented 10 years ago

When running the following from the UserController on Google Chrome, with ember-couchdb-kit-0.9, Ember Data v1.0.0-beta.3-56-g8367aa5, and Ember v1.0.0:

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();
            });
        }

with these models:

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')
});

neither the user nor the customer has their relationship set properly (the user has null and the customer has <computed>, rather than some sort of <EmberPromiseObject>). This only happens when the object in question is persisted. If the save() calls are omitted, both have correctly set relationships, but of course the database hasn't been updated with this information. Whenever the saves happen, the relationships are overwritten with empty entries.

I've changed my copy of serializeBelongsto to the following:

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;
      }
    }

console.log(Ember.get(belongsTo, attribute)); returns undefined, which I've tried to change to console.log(Ember.get(Ember.get(belongsTo, 'content'), attribute)); since console.log(belongsTo); told me the id attribute was hidden inside a content object. Attached is a screenshot showing what I mean. screenshot from 2013-12-07 18 15 52 The change doesn't fix the problem though, and I keep getting undefined.

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

OpakAlex commented 10 years ago

Can you create some test for this?

blainehansen commented 10 years ago

Sure I'd love to, how would you like me to do so? A fiddle?

blainehansen commented 10 years ago

Alright I'm working on one right now.

blainehansen commented 10 years ago

http://jsfiddle.net/faichenshing/Ember/151/ This is the best I can do. With such an interconnected system I'm not sure how to get it to work. The console throws a bunch of syntax errors about the adapter files. I've externally linked to the dest directory in my copy of the project, https://github.com/blainehansen/ember-couchdb-kit, where I've made the changes I've talked about to serializeBelongsTo.

OpakAlex commented 10 years ago

Can you create some jasmine spec?

OpakAlex commented 10 years ago

or fail tests for belongsTo ?

blainehansen commented 10 years ago

I've never done jasmine before, so I could try but I'd have to figure that all out first :/ I could do a pastebin of all the console outputs I get? Would that be helpful?

blainehansen commented 10 years ago

I'm trying to push my entire project to github. I'm having trouble. Excuse my inexperience :/

blainehansen commented 10 years ago

Here's a pastebin. Still working on pushing my project. http://pastebin.com/v4mb3PJ2

OpakAlex commented 10 years ago

create jasmine test, and i am fixed this bug if it reproduce in test.

blainehansen commented 10 years ago

Here's the whole project. https://github.com/blainehansen/studio/tree/master

I'll get working on the Jasmine, but there's no telling how long it will take me.

blainehansen commented 10 years ago

I figured out the problem. Basically the belongsTo object in serializeBelongsTo wasn't really resolved by the time it was being referenced, which I found out by querying isFulfilled. So I implemented by saving side this way:

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');
    });
}

Now everything works like a charm. It might be a good idea for serializeBelongsTo to take this into account though. This line: console.log(Ember.get(belongsTo, 'isFulfilled')); was coming up false in my case. There was just a race condition of some sort between the creation of the record and it's serialization!

Zatvobor commented 10 years ago

@blainehansen Is there still an issue for you?