I have a lot of images in the application and not necessary that one belongs to post. Then, I’m trying to push some images to Post from the controller (does not matter from where is this context)
I’m not getting the state before I have added the image, I’m mean: it is working fine for “title” but not for image_ids
Does any one know if it’s expecting behaviour?
And, btw why changing children records is not making parent ‘isDirty’ anymore…
Again: with rev13 was everything fine
I can’t find where I read it, but I know that part of the decision to deprecate DS.hasOne (which was just an alias for DS.belongsTo), was because that going forward parent-child relationships will dictate when a parent is considered dirty because of its children. However, this is still an outstanding task for the Ember Data team.
For now you’ll need to override isDirty and rollback (and perhaps save) to have the behavior you want:
DS.Model.extend({
// When the record is fetched, save its relations so they can be reverted
_saveRelations: function() {
var savedRelations = this._savedRelations = {};
this.constructor.eachRelationship(function(key, relationship) {
if (relationship.kind === 'hasMany') {
savedRelations[key] = this.get(key).toArray();
}
}, this);
}.on('didLoad', 'didCreate', 'didUpdate'),
// Rollback relations as well as attributes
rollback: function() {
// Revert attributes like normal
this._super();
// Revert relationships to their state at last fetch
if (this._savedRelations) {
Ember.keys(this._savedRelations).forEach(function(key) {
this.suspendRelationshipObservers(function() {
this.get(key).setObjects(this._savedRelations[key]);
}, this);
// Rollback child records that have changed as well (optional)
this.get(key).filterBy('isDirty').invoke('rollback');
}, this);
}
}
});
App.SomeModel = DS.Model.extend({
// Model is dirty if any child relations have changed
isDirty: function() {
return this._super('isDirty') ||
this._savedRelations && Ember.keys(this._savedRelations).any(function(key) {
// Deep compare requires Underscore.js
return !_.isEqual(this._savedRelations[key], this.get(key).toArray()) ||
this.get(key).anyBy('isDirty');
}, this);
}.property('currentState', /* list all relationships keys here with both `.[]` and `.@each.isDirty` */).readOnly()
});
Thank you very much for the insight.
This is very important part, which was changed without any notice in CHANGELOG.md.
Your solution seems the right way to generalise the fix, but for now I will stick to old straightforward way
Save the children before manipulation
Revert them, when hitting “Discard Changes”
At this point, after all pain, I have been through with Ember-data, I wish I have never choose it at first place.
@johnnyo I haven’t done the deep dive into ED relationships since the last major refactor, so I can’t say. It’s possible that it’s not even necessary anymore.
@johnnyo Sorry, you asked specifically about this.suspendRelationshipObservers, which I think may not be necessary anymore. Relationship dependent dirty tracking is certainly not supported by Ember Data.