Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Creating a child record in belongsTo doesn't update the parent's list of children. #544

Closed
darthdeus opened this Issue · 17 comments

10 participants

@darthdeus
Collaborator

I've had quite a hard time reproducting this in a JSFiddle, but I hope this is enough for illustration

http://www.emberplay.com/#/workspace/4205164642

Basically if I do something like this

var user = App.store.find(App.User, 1);
App.Post.createRecord({ title: "foo", user: user });
App.store.commit();

then the user's posts collection is not updated and still returns undefined

user.get("posts").objectAt(0)

I tried doing something like

didCreate: function(record) {
  this.get("user.posts").pushObject(this);
  App.store.commit();
}

which seems to work, sometimes. Sometimes I had the following error popup while developing my app

Uncaught Error: Attempted to handle event `becomeDirty`
on <App.Status:ember480:undefined> while in state
rootState.loaded.created.inFlight. Called with {}

and

Uncaught Error: Attempted to handle event `didChangeData`
on <App.Status:ember537:undefined> while in state 
rootState.loaded.updated.inFlight. Called with {}

but I haven't really been able to consistently reproduce those.

Is there a best practice for creating records in 1:N relationships?

@trek
Owner

I agree this should work, but until then try

user.posts.createRecord({title: 'foo'})
@darthdeus
Collaborator

@trek cool that works great :) But how should I do this when I have multiple relationships on the model? Such as

App.Status = DS.Model.extend({
  text:     DS.attr("string"),
  user:     DS.belongsTo("App.User"),
  timeline: DS.belongsTo("App.User"),
});

think of this as a facebook/twitter timeline.

In this case I would want both of the belongsTo relationships to update, not just the one I do the user.statuses.createRecord.

@darthdeus
Collaborator

@trek Also just realized another issue, which I'm not sure how related is to this but ... if I am sorting the collection on the server, I'm not sure how to handle that when I insert a new record. Should I also be sorting them client side, or re-fetch after each insert?

@ftokarev

+1

There is also a similar ticket: #529

This is a regression -- in my project createRecord() worked properly until I updated ember & ember-data to latest. I've digged a bit -- the reason is that DS.Model observers belongsToWillChange()/belongsToDidChange() are not triggered on createRecord().

@ftokarev

git bisect shows that commit #101173b41f1ec4daed0be81cbb4f778c6b4aa16a "Bump ember to master" introduced this issue.

@ftokarev ftokarev referenced this issue from a commit
@ftokarev ftokarev Failing test for #544 4b60d0e
@mbixby

@darthdeus In the meantime, you can probably create a filtered record array instead (if you use this just for accessing statuses)

App.User.reopen
  statuses: (->
    App.Staus.filter (status) => status.get('user') is this
  ).property()
@mbixby

@darthdeus If you want to keep your records sorted by date, you can either hook your views to arrangedContent of the array proxy (easier; with no performance loss) or manually change the proxy by moving the record resolution to the start of the proxy.content array.

@ftokarev

I've bisected ember.js - the commit emberjs/ember.js@ecd3161 by @ebryn introduced this issue.

@ebryn, can you take a look at this?

@ftokarev

@wagenet , @ebryn , any updates on this?

@ftokarev ftokarev referenced this issue from a commit
@ftokarev ftokarev Fix for #544 d19b334
@ftokarev

Turns out, if a record is materialized right before its properties are set, the issue disappears.

I wonder, are there any pitfalls with this solution?

@mspisars

Can someone review this? :+1:

@ftokarev

Just migrated to the 11th revision - this issue is no longer present.

@ashugit

I am having a problem with createRecord.
I have this relation

App.Contact  = DS.Model.extend({
  test: DS.belongsTo('App.Test')
})

App.Test  = DS.Model.extend({
  text: DS.attr('string'),
  contact: DS.belongsTo('App.Contact')
 })

Test is embedded always in Contact.

I am trying to create a new model object by calling transaction.createRecord(App.Contact), it fails to create Test object. If I make the relation Contact -hasOne-> Test to Contact -hasMany-> Test I am able to call createRecord.

I am not sure how to call createRecord for a new model object for the parent such that all children in one-to-one relationship get initialized.

Please help.

@pdf

EDIT: Scratch that, my problem is solved on master.

@sly7-7
Collaborator

@darthdeus Hi Jakub, what's the status of this ?

@topherdavis

Is putting the commit in an Ember.run.next an appropriate workaround?

@stefanpenner

this variation of the problem should be fixed on master, other variations (such as a new child being loaded from the server) are not yet, and new issues will be opened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.