Ember js - Hasmany relationships break after updating other tables

I am using Ember.js with a local storage adapter. I have a strange problem updating records.

I have a post and comment model with hasMany relationships:

App.Post = DS.Model.extend({ title: DS.attr('string'), comments: DS.hasMany('comment', { async: true }) }); App.Comment = DS.Model.extend({ message: DS.attr('string') }); 

These are my post and comment controllers:

 App.PostsController = Ember.ArrayController.extend({ newTitle: '', actions: { create: function() { var title = this.get('newTitle'); var post = this.store.createRecord('post', { title: title }); this.set('newTitle', ''); post.save(); } } }); App.CommentsController = Ember.ArrayController.extend({ needs: "post", post: Ember.computed.alias("controllers.post.model"), newMessage: '', actions: { create: function() { var message = this.get('newMessage'); var comment = this.store.createRecord('comment', { message: message }); var post = this.get('post'); var comments = post.get('comments'); if (comments.get('content') == null) comments.set('content', []); comments.pushObject(comment); comment.save(); post.save(); } } }); 

When you create hasMany records, relationships are updated correctly.

 { "App.Post": { "records": { "0v66j": { "id": "0v66j", "title": "post1", "comments": ["p31al", "tgjtj"] } } }, "App.Comment": { "records": { "p31al": { "id": "p31al", "message": "comment 1" }, "tgjtj": { "id": "tgjtj", "message": "comment 2" } } } } 

A problem occurred while editing the message. The relationship after editing the post has disappeared. I did a search and found this code:

 DS.JSONSerializer.reopen({ serializeHasMany: function(record, json, relationship) { var key = relationship.key; var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship); // alert(relationshipType); if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany' || relationshipType === 'manyToOne') { json[key] = Ember.get(record, key).mapBy('id'); // TODO support for polymorphic manyToNone and manyToMany // relationships } } }); 

This is a trick, and everything worked out perfectly. But now I have a different problem. If I edit any other entry, all identifier references are replaced with the whole object as follows:

 {"App.Post":{"records":{"0v66j":{"id":"0v66j","title":"post2","comments":[**{"message":"comment 1"}, {"message":"comment 2"}**]},"8nihs":{"id":"8nihs","title":"post3","comments":["b4v2b","dbki4"]}}}, "App.Comment":{"records":{"p31al":{"id":"p31al","message":"comment 1"},"tgjtj":{"id":"tgjtj","message":"comment 2"}, "b4v2b":{"id":"b4v2b","message":"comments3"},"dbki4":{"id":"dbki4", "message":"comments4"}}}} 

Comments refrences should be comments ": [" p31al "," tgjtj "] like this, but identifiers are replaced as" comments ": [ {" message ":" comment 1 "}, {" message ":" comment 2 "} ]

+62
javascript ember-data has-many
Oct 26 '13 at 7:40
source share
2 answers

When using ApplicationSerializer, which extends LSSerializer, it works.

Maybe it has been fixed since he asked?

+1
Apr 07 '15 at 17:58
source share

I noticed a few things in my way with Ember ... and especially Ember-Data.

One of them is when you deal with associations, which I had to manually add to associations, saving and rewriting, and use addObject for associations in memory, since you use a little here. :)

Please note that this only happens when I update several new objects at once. For example, if your post is new and your comment is also new.

I am a little worried to see the following code in your code base because it should not be there. You should never have null or non-array objects in your associations. I'm not sure what hacking you did with the adapter and why it was necessary, but I hope this is not the reason:

  if(comments.get('content') == null) comments.set('content', []); 

In any case, the following code is how I will probably write your action to create. This can help. I hope so.

 create: function() { // get the post for association on the new comment var post = this.get('post'); // get the message to store on the new comment var message = this.get('newMessage'); var comment = this.store.createRecord('comment', { message : message, post : post }); comment.save().then(function(savedComment) { post.get('comments').addObject(savedComment); }); } 

Please note that this is much easier. Typically, if you are doing complex complicated things, something is wrong, and it's time to go back to the basics and add one thing at a time, thoroughly testing between additions. :)

Good luck

-one
Apr 19 '14 at 6:56
source share



All Articles