My store has duplicate models (same ID)


#1

Maybe I’m making a poor assumption here, but it seems really odd that I’m ending up with models of the same class with the same id in my data store.

Using Ember Data : 1.0.0-beta.7.f87cba88

I’ve really been fighting ember-data and some of the issues with relations, and am pretty close to being satisfied with my solution, but this seems really wrong.

The project is a Quiz builder - the user creates a Quiz, then walks through a process of creating Questions, which each have their own related Answers (we can bracket the asnwers relation for now and focus only on the Quiz hasMany Questions).

App.Quiz = DS.Model.extend({
  name:           DS.attr('string'),
  questionsCount: DS.attr('string'),
  questions:      DS.hasMany('question')
});

App.Question = DS.Model.extend({
  text:       DS.attr('string'),
  humanIndex: DS.attr('number'),
  quiz:       DS.belongsTo('quiz', {embedded: 'always'}),
  answers:    DS.hasMany('answer', {embedded: 'always'})
});

App.Router.map(function() {
	this.route('index', {path: '/'});
        this.resource('quiz', { path: '/quiz' }, function() {
	  this.resource('questions', {path: ':quiz_id/questions'}, function(){
	    this.resource('question', {path: ':question_id'}, function(){
              this.route('edit');
	    });
	})
        this.route('new');
	this.route('show', {path: ':quiz_id'});
  });
});


// this is a basic form for a Quiz, calls the startQuestions action in controller

App.QuizNewRoute = App.AuthenticatedRoute.extend({
  model: function() {
    return this.store.createRecord('quiz', {});
  }
});

App.QuizNewController = Ember.ObjectController.extend({
  needs: ['index'],
  numQuestionOptions: ['1', '2', '3', '4', '5'],	
   
   actions: { 		
     startQuestions: function(){
	var self = this;
        this.get('content').save().then(
	    function(quiz){
	      self.transitionToRoute('question.edit', quiz, quiz.get('questions.content')[0].id));
	    }
	 ).catch(
	 function(error){...});		
	}		
 }
});

When the user saves the quiz, my server creates persisted Questions, and returns the entire Quiz model with Question models side loaded:

{
  "questions": [
    {
      "id": "5327428356617925f3610400",
      "quiz_id": "5327428356617925f3600400",
      "text": null,
      "human_index": 1,
      "answer_ids": [
        
      ]
    },
    {
      "id": "5327428356617925f3620400",
      "quiz_id": "5327428356617925f3600400",
      "text": null,
      "human_index": 2,
      "answer_ids": [
        
      ]
    },
    {
      "id": "5327428356617925f3630400",
      "quiz_id": "5327428356617925f3600400",
      "text": null,
      "human_index": 3,
      "answer_ids": [
        
      ]
    }
  ],
  "answers": [
    
  ],
  "quiz": {
    "id": "5327428356617925f3600400",
    "questions_count": 3,
    "name": "This is the new quiz",
    "question_ids": [
      "5327428356617925f3610400",
      "5327428356617925f3620400",
      "5327428356617925f3630400"
    ]
  }
}

All good so far. The ember chrome extension shows that the data was loaded into the store properly, with 1 Quiz and 3 questions, all with references to each other.

Here is the Route for the question edit

App.QuestionEditRoute = Ember.Route.extend({
	
	model: function(params){
		return this.modelFor('question');
	},
	
	setupController: function(controller, model){
		var quiz	   = this.modelFor('questions');
		var question = this.modelFor('question');

		controller.set('content', question.get('content')); 	
		controller.set('quiz', quiz);
		controller.set('question', question);

		}
});

The problem comes when I try to then save a question. I’m purposely throwing an error on the server, so I know that this is more of a client side issue, but I can’t wrap my head around it. As soon as I call

self.get('question').save()

in the controller, a second Quiz is created in the store, with the same id as the one that already exists, but with all of the other attributes undefined. I can’t upload an image to show the chrome extension, but form the console:

_.each(App.__container__.lookup('store:main').all('quiz').get('content'), function(quiz){ console.log(quiz.id)});
  5327491356617925f3750400 
  5327491356617925f3750400 
[Class, Class]

So what could be going on here? I recognize the problems with embedded documents, and saving a parent/child at the same time. But that’s why I designed my API this way, to create persisted container children objects when the parent is created. But somewhere along the way Ember is losing sight of the fact that those Question model instances belongTo the Quiz that is in the store and persisted.

I’ve tried so many things, including pushing the Question into quiz.questions right before save. I also have played with a number of serializer overrides.

Lastly, things work great when I hit the question edit route from a hard refresh - the quiz and children questions are pulled down, and saving questions posts successfully without creating a second quiz object. This leads me to think it has to do with the route’s model() or setupController() actions.

Any help would be much appreciated. Happy to include more code as well.