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

When belongsTo change, record does not set dirty. #1367

Closed
franciscodelgadodev opened this issue Sep 25, 2013 · 14 comments
Closed

When belongsTo change, record does not set dirty. #1367

franciscodelgadodev opened this issue Sep 25, 2013 · 14 comments

Comments

@franciscodelgadodev
Copy link

I'm having a problem when a belongsTo relationship change.

I have these models:

App.User = DS.Model.extend({
  email: DS.attr('string')

  posts: DS.hasMany('post')
});

App.Post = DS.Model.extend({
  name: DS.attr('string')

  user: DS.belongsTo('user')
});

and the controller:

get = Ember.get

App.PostController = Em.ObjectController.extend({
    userChanged:  function(){
      model = get(this, 'model')
      console.log(get(model, 'isDirty')); // => false
    }.observes('user')
});

When the user change in post it is not set dirty.

I wonder if it is the expected behavior.

Thank you!

@dagda1
Copy link

dagda1 commented Sep 25, 2013

I have exactly the same problem with 0.14 and ember 1.0. None of my belongsTo relationships dirty the model when they change.

The model does get dirtied with rc7 and 0.14 so something in 1.0 is breaking it.

I am thinking it might be the observer changes from rc8/1.0.

@wycats
Copy link
Member

wycats commented Sep 26, 2013

Nope. This is currently intentional. The dirty flag is only set when attributes are changed at the moment. In 1.0, you can save() a clean record, so most of the impetus for complex dirty tracking was removed.

It would be nice to be able to see whether any associated relationship has local changes, and this is a goal of the upcoming relationship improvements. Merging this into the meta relationships ticket.

@wycats wycats closed this as completed Sep 26, 2013
@wycats
Copy link
Member

wycats commented Sep 26, 2013

Merged into #1308.

@wycats wycats mentioned this issue Sep 26, 2013
3 tasks
@dagda1
Copy link

dagda1 commented Sep 26, 2013

I am seeing this behaviour with 0.14 and the record is dirtied with ember rc7. We are beta with a product as this is a big problem for us. Can anyone point me in the right direction of where to start looking in the 0.14 code base as to why it does not happen against the 1.0 code base .

@SirZach
Copy link

SirZach commented Oct 18, 2013

What if you are wanting to perform specific user interaction based on the dirtiness of the model? For example, if a user leaves the page without saving the model (via submit), prompt a warning about unsaved changes?

@ahacking
Copy link
Contributor

ahacking commented Oct 7, 2014

I was originally wanting to see this functionality in Ember Data, however after giving it some thought and looking at various alternatives and the use cases for where I need to track dirty changes, I am of the view including dirty tracking on model relationships is actually the wrong place and potentially harmful.

If you consider that your application state is an arbitrary graph of model objects, dirtying a single object has the capacity to dirty the large part of object graph as models in moderate to complex applications typically end up fairly well connected. It is the controller that has the knowledge of what models should be considered 'in scope' for dirty tracking within a particular editing context.

Given this, I have found that where I have relationships that are being rendered in views for editing, I use the render helper which instantiates a controller which wraps the related model and simply informs the parentController when its content has become dirty or changed in some way (works great for embedded hasMany relationships, or relationships that require the parent to exist first). This avoids run-away object graph dirtying as would occur at the model layer as dirtying is contained to just what is being edited as a first class controller concern.

The last thing I want is changing a single property on a model causing a whole lot of dirty tracking activity across the object graph because the models (quite correctly) have no concept of editing context. Keeping dirty tracking specific to a particular editing context at the controller level is IMO the "right way". It also works well when using a buffered proxy to keep changes isolated until the user commits via 'save'/'accept' as well as allowing editing concurrently with in-flight requests.

@wycats Do you have any views on whether relationship dirty tacking should still be a feature or not? I am concerned that if this feature is added, developers will need to control dirty tracking via options on model relationships to try and align with how the models are actually used in different editing contexts. They will also want to tame unwanted performance issues caused by run-away dirty tracking. This just smells of mis-feature.

@wycats
Copy link
Member

wycats commented Oct 7, 2014

@ahacking The more we've been mulling this over, the more we think that dirty tracking ends up actually being an application level feature. In other words, instead of letting the adapter dirty arbitrary amounts of the graph (which gets increasingly complex over time), the application says which sides of the relationships should be dirtied.

In previous versions of Ember Data, dirtying controlled saving. In Ember Data 1.0, dirtying is primarily useful for the UI, which is further indication that it's an application-level concern. You now save records explicitly, instead of letting Ember Data automagically try to guess what to save based on dirtiness.

I think this satisfies your desires 😄

@ahacking
Copy link
Contributor

ahacking commented Oct 7, 2014

@wycats Agree that the previous versions ended up in a difficult place and the current approach is far more pragmatic.

Without more detail its hard to tell if it satisfactory :)

My concern is how the dirty tracking gets expressed. It seems natural to me that the UI structure (ie templates) drive what models are in scope for edit and the controller hierarchy that results to support that. I am concerned that if relationship dirty tracking is expressed on the models then it can't take into account different editing contexts within the application. For example in a list view I may have an up/down vote which is only concerned with dirtying a single property on a model with an implicit save, vs a full edit of a model including some closely related models, or conversely editing a related model from the inverse side (consider a sub-task due date extending the parent task due date). How would these competing dirty rules get expressed? How do you avoid leaving the object graph in a dirty state if the controller is only concerned with saving within the boundary of objects it cares about? ie in one case the controller/route calls save on a single model whilst in another case it also saves related models, but if the dirty boundary doesn't match what the controller/route saves is there a possibility that remaining parts of the object graph could now be reflecting a dirty state?

My main point is that the controller hierarchy that falls out from template rendering provides a natural boundary around the model/dirty set without additional rules needing to be expressed at a lower layer. If expressed at another layer it may not necessarily align with the particular controller/view context as there is a risk of either over or under stating the dirty propagation. Managing dirty state at the controller level also keeps the dirty state management to a minimum of what can be modified in the particular edit context/view hierarchy and avoids spamming the model graph with computed property invalidations/updates that don't apply to the edit context.

@timrwood
Copy link

I've opened an RFC for this issue. Please weigh in.

emberjs/rfcs#21

@igorT igorT mentioned this issue Dec 10, 2014
28 tasks
@arenoir
Copy link
Contributor

arenoir commented Dec 10, 2014

It seems intuitive to me that if you change the user of the post then the primary_key post.user_id would be changed thus making sense that the post be marked dirty.

@lolmaus
Copy link
Contributor

lolmaus commented Jan 6, 2015

Learning Ember, stumbled upon the necessity in subj.

I resolved the necessity with a small mixin:

Do you think it's a feasible solution?

@bmac
Copy link
Member

bmac commented Feb 19, 2015

Re-opening because it looks like the issue this was merged into has been closed.

@bmac bmac reopened this Feb 19, 2015
@Chun-Yang
Copy link

Hey @bmac , it seems this issue is being discussed at emberjs/rfcs#21.

@igorT
Copy link
Member

igorT commented May 25, 2015

Tracking this under #2122

@igorT igorT closed this as completed May 25, 2015
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