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

Updating child model with belongsTo does not update the parent model's hasMany #412

Closed
jlommori opened this issue Jul 15, 2016 · 1 comment

Comments

@jlommori
Copy link

Version Information

DEBUG: -------------------------------
DEBUG: Ember      : 2.6.0
DEBUG: Ember Data : 2.6.1
DEBUG: Firebase   : 3.0.5
DEBUG: EmberFire  : 2.0.1
DEBUG: jQuery     : 2.2.2
DEBUG: -------------------------------

Description

When working with relationships that have hasMany and belongsTo relationships, it seems EmberFire does not automatically update a parent model's hasMany reference when a child record with belongsTo is added. For example, if I have two models framework and question, where a question has a belongsTo relationship to a framework and a framework has a hasMany relationship to it's questions. Please see the models below:

// -- Frameworks Model
import DS from 'ember-data';
const { attr, hasMany } = DS;

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    questions: { serialize: 'ids' }
  } 
});

export default DS.Model.extend({
  name: attr('string'),
  reports: hasMany('report'),
  questions: hasMany('question', {async: true}),
  includedFramework: attr('string'),
  reportOnlyOnce: attr('string', { defaultValue: false }),
  frameBuilder: attr('string', {defaultValue: "none"}),
  createdAt: attr('string'),
  createdBy: attr('string'),
  updatedAt: attr('string'),
  updatedBy: attr('string')
});
// -- Question Model
import DS from 'ember-data';
const { attr, hasMany, belongsTo } = DS;

export default DS.Model.extend({
  framework: belongsTo('frameworks', {async: true}),
  detail: attr('string'),
  type: attr('string'),
  createdAt: attr('string'),
  createdBy: attr('string'),
  position: attr('number'),
  options: hasMany('option')
});

Expected behavior

When a new question is added and has a valid entry for framework belongsTo, it would be expected that on newQuestion.save() for example, both question model would be updated with the framework belongsTo entry AND the framework model would be updated automatically with the revised hasMany list of questions in the framework model.

Actual behavior

Unfortunately, when a new question is added, there seems to be no update to the framework model and therefore, the questions hasMany list is not updated. After investigating the emberfire/app/adapters/firebase.js file, it seems there is no call on a belongsTo relationship that would trigger the save of the "parent" model.

I have found however that the following work around does solve the problem:

      newQuestion.save().then(function() {
            self.store.findRecord('framework', params).then(function(framework) {
              framework.save();
            })
          });

If a newQuestion is added to the local store and saved in Firebase, the next time I call a framework.save() the entire questions hasMany field was updated correctly. Adding this small framework.save() after saving a to the question model has solved my problem, however it seems to be a work around in my opinion.

But maybe this bug is a feature, and I don't realize the downfalls to doing this automatically. Thoughts are welcomed as I'm quite new to Ember and EmberFire. Thanks for the great library regardless!

@tstirrat
Copy link
Contributor

tstirrat commented Jul 19, 2016

Hey, sorry for the delay!

When it comes to async relationships it's by design. These situations need to be accounted for by the developer. Unfortunately, it's not simple to infer what the developer needs in these situations.

Consider some examples:

  • You have pending changes to the parent model (frameworks), you call question1.save(). Should all the pending changes on the parent be saved, or just the hasMany links? Saving the parent could produce unexpected results for some developers.
  • You're editing the parent, you add a child, we go ahead and update the parent. Then you decide to cancel the parent changes with parent.rollback(). Should we revert the parent.children change too? only the developer truly knows what should happen here.

So in your example, the workaround you gave is what I do, and most others do:

return child.save().then(child => child.get('parent').save());

Embedded records are a little bit different. With these, if you save the parent, we can be more sure that saving all children is ok, given that everything lives under the same structure in the DB.

*edit for clarity in second example

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

3 participants