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

A record in the invalid state becoming valid keeps the same transaction #539

Closed
wants to merge 2 commits into from

Conversation

cyril-sf
Copy link
Contributor

This is fixing the issue "unable to reuse a transaction on an invalid record"

[Fixes #457]

@cyril-sf
Copy link
Contributor Author

cyril-sf commented Jan 2, 2013

@tomdale @wycats

Hey guys, any chance someone can take a look at this PR and let me know if that's right or what you would expect otherwise?

Thanks

cc @dgeb

@wagenet
Copy link
Member

wagenet commented Jan 9, 2013

@cyril-sf it looks like this has some merge conflicts. Can you rebase on master?

@cyril-sf
Copy link
Contributor Author

cyril-sf commented Jan 9, 2013

Sure.

@cyril-sf
Copy link
Contributor Author

cyril-sf commented Jan 9, 2013

I didn't get any conflicts, weird. Did I miss something?

@dgeb
Copy link
Member

dgeb commented Jan 9, 2013

@wagenet I didn't get any conflicts either ... could you please verify?

@wagenet
Copy link
Member

wagenet commented Jan 9, 2013

That's odd, it says it can be merged now.

@cyril-sf
Copy link
Contributor Author

cyril-sf commented Jan 9, 2013

It's not odd, it's wonderful!

@cyril-sf
Copy link
Contributor Author

@wagenet @dgeb

Any feedback on this PR?

@cyril-sf
Copy link
Contributor Author

After a discussion with @wycats and @tomdale, this isn't the right approach. I will add a new bucket for erred records that can be retried within the same transaction.

@sapientpants
Copy link

@cyril-sf Is there anything I can help with on this?

I've been trying a number of approaches to be able to correct and resubmit after a server validation failure and have yet to find anything that works.

@cyril-sf
Copy link
Contributor Author

@Pansapien thanks for the help. I'm finishing another PR right now and should work on fixing this one before the end of the week. Hopefully the code will be ready next week and will be good enough to be accepted. But my company really needs this too, so I won't give up.

@cyril-sf
Copy link
Contributor Author

Let's summarize where I am with this:

  1. A record in the invalid state is in the inflight bucket.
  2. When one of its property is modified, didSetProperty will transition the record in the uncommitted state. With 2 effects:
    • When exiting the invalid state, we move the record from the inflight bucket to the clean one and we attach the record to the default transaction ( recordBecameClean )
    • When entering the uncommitted state, we move the record from the clean bucket to the dirtyType one and mark the record as dirty, preventing it from being moved to another transaction.

My solution was to move the record to the clean bucket when exiting the invalid state without modifying the transaction. It works in my case.

@wycats and @tomdale suggested to create a new bucket for erred records that could be retried (my understanding was that retry should be different from commit and take care only of erred records). I tried this approach by putting the record in an erred bucket when entering the invalid state and not doing anything on exit. We enter the uncommitted state from 2 different states:

  • we followed the happy path and the record is in the clean bucket
  • something went wrong and the record is in the erred bucket.
    which prevents us from using removeFromBucket (because we expect the record to be in the clean bucket.

I'm not sure to know how do you want to solve this problem.

@SweeD
Copy link

SweeD commented Jan 28, 2013

Is there anything new on this one? 😏

@ulisesrmzroche
Copy link

This is a feature that is very sorely needed. In the meantime, whats the alternative? How do I handle this scenario in my application?

@bobbus
Copy link
Contributor

bobbus commented Jan 30, 2013

👍 for a way to solve this in current master

@seanrucker
Copy link

Desperately need a fix for this. @cyril-sf anything I can do to help?

@dmonagle
Copy link

Hi guys, I have a workaround that I have been using with success. It isn't (can't be!) the best way of doing things going foward. But I have created a mixin for these purposes.

Gist: https://gist.github.com/intrica/4773420

The original SO question that I created in order to solve this:

http://stackoverflow.com/questions/14741377/what-can-you-do-with-ember-data-models-when-in-the-error-state

@cyril-sf
Copy link
Contributor Author

@seanrucker Sorry, I have been working on another PR for a while. I still plan to work on it once I'm done with the polymorphic associations.

@wulftone
Copy link

This is a pretty big one! Users often submit invalid data. I'm just learning ember-data, but quickly encountered this issue. Thanks, @intrica, for the gist! That was very informative.

@wulftone
Copy link

I have a super hacky fix for this in the meantime:

App.MyModel = DS.Model.extend({
  becameInvalid: function(model){
    model.send('becameValid');
  }
});

..at least for the Rails returning 422 because of validation errors issue.

Yeah....awesome! : P

@balinterdi
Copy link
Contributor

I don't see why the record has to be taken out of its transaction upon the invalid -> uncommitted transition. In my case it causes a mess since the record thus gets added to the default transaction and when I submit the form (save gets called on the adapter) it submits all records in it.

@cyril-sf 's above commit seems all that's needed. Instead of calling recordBecameClean which removes the record from the transaction, just call recordIsMoving which just adds the record to the clean bucket.

I'm also curious to see what does putting once-invalid records to a separate bucket (called erred) buys us. Why not just put it into the created/updated one? I guess an equivalent question is how is retry different then commit?

@justinfaulkner
Copy link

@tomdale
Copy link
Member

tomdale commented Apr 6, 2013

@cyril-sf What's the status of this?

@cyril-sf
Copy link
Contributor Author

cyril-sf commented Apr 6, 2013

@tomdale I'm going to work on that.

If anyone else wants to work on it, I'd be happy to help. But this is a big issue and someone needs to tackle it.

@dev-inigmas
Copy link

@wulftone Thanks for sharing your hacky solution, btw. It really helped me move on from this situation quickly.

@balinterdi
Copy link
Contributor

I'd happy to lend a hand but first I'd have to understand what's the desired behavior and the reasons behind it (see my comments above).

@ybart
Copy link

ybart commented Apr 11, 2013

@cyril-sf What are the remaining tasks needed for the PR to become ready to be merged ? You previously wrote you were not sure about how the team wanted it to be done, is there an update on this specific point ?

@cyril-sf
Copy link
Contributor Author

@balinterdi agreed.

@ybart This PR may be to specific, there are other areas that would need a robust error handling. Another frequent use case, is when you get a 500. You end up with a "zombie" record. The goal would be to list those use cases and design a solution that will lead us to fix them all, even if it is separated in several PR.

So the first step is really to list the error use cases.

@Emerson
Copy link

Emerson commented Apr 12, 2013

New to ember-data and ran into this today. Would be nice to see this merged, even if it's not the final solution (as mentioned in the above comment).

Update Thanks @wulftone for your hacky fix. Worked perfectly for me.

@sly7-7
Copy link
Contributor

sly7-7 commented Apr 19, 2013

@cyril-sf could you check if this is resolved ?

@cyril-sf
Copy link
Contributor Author

@sly7-7 The test that I have written doesn't pass in master with that commit.

I'll take a look at this code durig the weekend. Hopefully something good will come out of it.

@sly7-7
Copy link
Contributor

sly7-7 commented Apr 19, 2013

This would be great, thanks a lot :)

@tchak
Copy link
Member

tchak commented Apr 27, 2013

@cyril-sf I think this is fixed by transactions refactoring. Could you confirm that?

@cyril-sf
Copy link
Contributor Author

@tchak Confim! The record stayed attached to the transaction and can be attached to another one! Thanks!

@cyril-sf cyril-sf closed this Apr 28, 2013
@abobwhite
Copy link

@wulftone Your hack worked for me as well! Dang! I've been searching for a workaround for two days. How is it possible that this was overlooked? Obviously you need server side validation. According to the code, ember data expects a 422 for validation errors. But regardless whether it's a 422 or 500, the model is hosed, albeit in different ways. It should be easy to try to commit again. model.send('becameValid') goes against the grain in so many ways...a model shouldn't be valid if it's technically invalid. Plain a simple: a model in an invalid state should be able to commit.

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

Successfully merging this pull request may close these issues.

unable to reuse a transaction on an invalid record