As seems to be the case with most everything I do with ember-data the simple test case is very simple but anything \"real\" falls apart quickly due to my lack of understandi
I'm just figuring this out myself, but I just did it this way and it works…
For starters, when you this.store.createRecord('basket', {})
it should come with an empty array for its fruits
property. So, do this:
var basket = this.store.createRecord('basket', {});
basket.get('fruits').addObject(this.store.createRecord('fruit', {
name: 'orange',
color: 'orange'
}));
basket.get('fruits').addObject(this.store.createRecord('fruit', {
name: 'banana',
color: 'yellow'
}));
Incidentally, the empty fruits
array is actually a DS.PromiseArray
(which may instantly resolve to a DS.ManyArray
?), a more specific subclass of Ember.Array
, so that could make a difference.
However, what I found was that the fruits
property wouldn't get serialized at all--I'm using the JsonApiAdapter though, so that could be the reason. Or it might be that this is the expected behavior when the hasMany
child objects haven't been persisted yet. Anyway, I just did something like this in my controller's actions.save method:
basket.save().then(function(){
var promises = Ember.A();
basket.get('fruits').forEach(function(item){
promises.push(item.save());
});
Ember.RSVP.Promise.all(promises).then(function(resolvedPromises){
alert('All saved!');
});
});
Somehow, magically, when all that was done, I ended up with a saved "basket", with a generated id
, and saved "fruits" with generated id
s. And, all the fruits' belongsTo
properties pointed back at the basket, and the basket's hasMany
contained all the fruits…despite the fact that, when I save()
d the basket, the response from my backend returned an empty array for my fruits
property, which I was sure would mess things up but somehow didn't.
Of course, these weren't my actual models, but the parallel was very close. I'm on Ember Data 1.0.0-beta5 and Ember 1.3.1. I'm not using the stock REST adapter, but the JsonApiAdapter is a pretty thin shell over it--so try this approach and see if it works!
I've opened a similar question here that addresses a problem I encountered using the above code to also update existing records (as opposed to creating new ones). That solution is more general and detailed but more complex.
Also, another potential gotcha I ran into is that when (in this example) the basket
is created, the fruits
property (which is a DS.PromiseArray
) may not be fully ready yet. So you may need to do it like this instead:
var basket = this.store.createRecord('basket', {});
basket.get('fruits').then(function(){
// Now the fruits array is available
basket.get('fruits').addObject(this.store.createRecord('fruit', { /* ... */ }));
});