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

Added option to allow merging invalid changesets #74

Merged
merged 15 commits into from
Jul 22, 2016

Conversation

ivanvanderbyl
Copy link
Contributor

From discussion in #66

@poteto
Copy link
Collaborator

poteto commented Jul 19, 2016

I was actually thinking merge would merge changesets regardless of validity by default. I think it was too heavy handed in the beginning - the user should be able to decide since the changeset can only be executed if it is valid. What do you think?

@ivanvanderbyl
Copy link
Contributor Author

Yeah, totally, I'm happy with that. PR updating...

@ivanvanderbyl
Copy link
Contributor Author

ivanvanderbyl commented Jul 19, 2016

Hmm so some thoughts on merging logic:

Let's assume we have the following (taken from readme):

let changesetA = new Changeset(user, validatorFn);
let changesetB = new Changeset(user, validatorFn);
changesetA.set('firstName', 'Jim');
changesetA.get('errors') // [{key: "firstName", value: "Jim", validations: ["Firstname cannot be Jim"]}]
changesetB.set('firstName', 'Jimmy');
changesetB.set('lastName', 'Fallon');
let changesetC = changesetA.merge(changesetB);

Now if we merge changesetA which has an invalid firstName, and changesetB, which does not have an invalid firstName, what should happen?

  1. We pick the one with the valid attr and keep that,
  2. We don't merge the attr because one of them has errors,
  3. We assume merging order indicates intention and B.firstName replaces A.firstName, and does not copy errors from A.

Thoughts?

@ivanvanderbyl
Copy link
Contributor Author

Essentially what I'm getting at is, after merging you shouldn't end up with changes on firstName and errors on firstName

@poteto
Copy link
Collaborator

poteto commented Jul 19, 2016

Yup agreed, I think it should work the same way Object.assign does -- the last object should override any previous value from previous objects

let errorsB = get(changeset, ERRORS);
let mergedErrors = pureAssign(errorsA, errorsB);
newChangeset[ERRORS] = mergedErrors;
newChangeset.notifyPropertyChange(ERRORS);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sidenote: use this._notifyVirtualProperties();

@ivanvanderbyl
Copy link
Contributor Author

I think that makes sense, I'll reject keys from errors on A which are present changes of B. That actually would make logical sense in my form because each section is merged from top to bottom.

@ivanvanderbyl
Copy link
Contributor Author

@poteto I think this solves it ^^


```js
let changesetA = new Changeset(user, validatorFn);
let changesetB = new Changeset(user, validatorFn);
changesetA.set('firstName', 'Jim');
changesetA.get('errors') // [{key: 'firstName', value: 'Jim', validations: ['Firstname cannot be Jim, sorry Jim']}]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: prefer having spaces within {}, e.g. [{ key: ... }]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this addition helps with understanding how merge works, feels like it could be confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaned that up

@ivanvanderbyl
Copy link
Contributor Author

Ready to roll

changesetB.set('lastName', 'Fallon');
let changesetC = changesetA.merge(changesetB);
changesetC.execute();
user.get('firstName'); // "Jimmy"
user.get('lastName'); // "Fallon"
```

When merging, the changeset being merged in takes precedence. For example: if `B` contains errors, the errors from `B` will be merged, and the invalid attributes on `B` will not be merged from `A` even if they're valid on `A`. Likewise, if `A` contains errors on attributes which are valid on `B`, the value from `B` will be used and the errors for those keys will not be merged from `A`. This is to prevent the new changeset from containing `changes` and `errors` on the same keys, which is a guarantee of a normal changeset.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still confusing, in fact I think it would be better to just remove all the changes to the readme and only keep the change on L383. I feel like this is just implementation detail that the end user doesn't need to know about.

@poteto
Copy link
Collaborator

poteto commented Jul 21, 2016

Sorry about the delay, was out the whole day! Just a minor update to the readme and we're good to go

@ivanvanderbyl
Copy link
Contributor Author

@poteto :shipit: ?

@poteto
Copy link
Collaborator

poteto commented Jul 22, 2016

Yes, thanks for this!

@poteto poteto merged commit 85337fc into adopted-ember-addons:master Jul 22, 2016
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.

2 participants