Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stumped on save behavior using belongsTo #48

Closed
brancusi opened this issue Apr 20, 2014 · 10 comments
Closed

Stumped on save behavior using belongsTo #48

brancusi opened this issue Apr 20, 2014 · 10 comments

Comments

@brancusi
Copy link
Contributor

I am trying to create a simple relationship between items, units, and conversions. For some reason, when I create the reverse, "belongsTo" on the model, it doesn't save the references.

So I am trying to create a relationship as follows:

Conversion Model

export default DS.Model.extend({
    order: DS.attr('number'),
    quantity: DS.attr('number'),
    unit: DS.belongsTo('unit', { async: true }),
    item: DS.belongsTo('item', { async: true })
})

For some reason if I put the reverse "belongsTo" on the Conversion model, it won't save to the conversions array. If I remove it, it works. Results are below.

Unit Model

export default DS.Model.extend({
    name: DS.attr('string'),
    gramMultiplier: DS.attr('number'),
    conversions: DS.hasMany('conversion', { async: true })
})

Item Model

export default DS.Model.extend({
    name: DS.attr('string'),
    cost: DS.attr('number'),
    conversions: DS.hasMany('conversion', { async: true })
});

Item Index Controller

var Promise = Ember.RSVP.Promise;

export default Ember.ArrayController.extend({
    newItemName:'Straight torture son!',
    unitTypes:null,

    actions: {
        createItem:function(){
            var item = this.store.createRecord('item', {name:this.get('newItemName'), cost:1});
            var conversion = this.store.createRecord('conversion', {item:item, order:0, quantity:1, unit:this.get('unitTypes').objectAt(0)});

            var promiseCollection = [item.save(), conversion.save()];

            this.set('newItemName', '');

            Ember.RSVP.all(promiseCollection).then(function(fulfilled){
                Promise.cast(item.get('conversions')).then(function(conversions){
                    conversions.addObject(conversion);
                    item.save();
                });
            });
        }
    },
});

Firebase - Without belongsTo refs on the Conversion model

{
    -JKxfFa2G9TDkZ5mM-S8: {
        cost: 1,
        conversions: {
            -JKxfFa4MGiZI9P-hQCi: true
        },
        name: "Straight torture son!"
    }
}

Firebase - WITH belongsTo refs on the Conversion model

{
    -JKxa6nDwGVZtzDMNdsd: {
        cost: 1,
        name: "Straight torture son!"
    }
}

Questions

  1. I am going off of the article https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html - Does this pretty much still stand? Is the preferred method to leave dangling references?
  2. Is there a better way to grab a hasMany array to fill? Rather than: Promise.cast(item.get('conversions'))
@aputinski
Copy link
Collaborator

@brancusi I'll try to take a look this week. Thanks for all the context!

@rickharrison
Copy link

I also had this issue and taking out the belongsTo fixed it for now.

For #2, I think that you can just do item.get('conversions').then(function() {...})

@neverfox
Copy link
Contributor

I'm having the exact same problem, with the exact same "fix." I'm new to the library as of today (coming from Fireplace), but I imagine this has to be a relatively new bug (assuming that's what it is), given that this is a pretty common scenario that wouldn't have gone unnoticed all the way to a 1.x.x release. It took me all of an hour to run into it. Let me know if I can help try out different scenarios.

@neverfox
Copy link
Contributor

I should ask, is it more idiomatic to set the belongsTo objects when creating those records (item and unit on the conversion record) and before doing the addObject, like in @brancusi's example? Or to create the record without them, do the addObject, and then all the saves last? Both approaches seem to give identical results.

@neverfox
Copy link
Contributor

The problem is in ember-data's JSONSerializer here. The only types of relationships that it serializes (1.0.0-beta7) are manyToNone (which is why it works when you drop the belongsTo) and manyToMany. Without the serialized JSON, you won't get the saved references. I don't know if it has always been like this without searching though the commits.

@neverfox
Copy link
Contributor

According to the notes on the commit for this method, it was the intention of the developers that you would have to override it if you needed to save the ids on the hasMany side. We're not the first to be surprised. It looks like emberfire will have to override this method.

@brancusi
Copy link
Contributor Author

@neverfox nice find! Thank you!

@neverfox
Copy link
Contributor

You're welcome. I was in a bind myself, so I needed it to work. Hopefully, the pull request I submitted is acceptable.

@brancusi
Copy link
Contributor Author

I hope so too.

@brancusi
Copy link
Contributor Author

Works thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants