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

fix creation of LB4 models with auto-generated id #553

Merged
merged 1 commit into from
Nov 22, 2019

Conversation

bajtos
Copy link
Member

@bajtos bajtos commented Nov 21, 2019

  • Add a try/catch block to prevent coerceId from crashing the process on uncaught exception (forward the coercion error via callback).

  • Fix isObjectIDProperty to use the correct ObjectID constructor in instanceof check.

This fixes the problem described in loopbackio/loopback-next#4059 (comment).

Checklist

👉 Read and sign the CLA (Contributor License Agreement) 👈

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • Commit messages are following our guidelines

- Add a try/catch block to prevent `coerceId` from crashing the process
  on uncaught exception (forward the coercion error via callback).

- Fix `isObjectIDProperty` to use the correct ObjectID constructor
  in `instanceof` check.

Signed-off-by: Miroslav Bajtoš <[email protected]>
Copy link
Contributor

@agnes512 agnes512 left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@agnes512
Copy link
Contributor

I checked all the mongo id test cases, I try to summarize the CRUD behavior on strictObjectIDCoercion and dataType: ObjectID cause I didn't find any documentation to describe it:

strict::x:type::x: strict::heavy_check_mark: type: ❌ strict: ❌ type: ✔️ strict: ✔️ type: ✔️
create with ObjectId T unknown unknown T
create with objId-like-str T T unknown T , returns ObjectID
create with invalid str T F unknown F
find withObjectId T T , returns str id unknown T, type overrides, returns ObjectID
find with objId-like-str T unknown unknown T , bc strict is true
update with ObjectId T unknown unknown T bctype is set
update with objId-like-str T unknown unknown T bctype is set

Please correct me if anything is incorrect.

@bajtos
Copy link
Member Author

bajtos commented Nov 22, 2019

@agnes512 It's a great idea to document behavior for different combinations of strictObjectIDCoercion and dataType: ObjectID, maybe we can add this table to connector's README file?

To be honest, I find it difficult to understand the values in table cells. What does it mean when the value is T, F or unknown?

I think that my pull request should not be changing the behavior, I am just fixing an incorrectly written instanceof check that prevented the create operation from returning data back to the user.

Copy link
Contributor

@hacksparrow hacksparrow left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member Author

@bajtos bajtos left a comment

Choose a reason for hiding this comment

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

Posting few comments to capture what I learned while making this change.

@@ -1963,7 +1969,7 @@ function isObjectIDProperty(modelCtor, propDef, value, options) {
if (typeof value === 'string' && value.match(ObjectIdValueRegex)) {
if (isStoredAsObjectID(propDef)) return true;
else return !isStrictObjectIDCoercionEnabled(modelCtor, options);
} else if (value instanceof ObjectID) {
} else if (value instanceof mongodb.ObjectID) {
Copy link
Member Author

Choose a reason for hiding this comment

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

ObjectID is a factory function that creates new mongodb.ObjectID, it's not a class. Therefore the expression value instanceof ObjectID is never true.

type: 'string',
id: true,
generated: true,
mongodb: {dataType: 'ObjectID'},
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the property definition used in LB4.

When the primary keys is auto-generated by the database, juggler replaces the type provided by the user (string) with the type defined by the connector (mongodb.ObjectID).

As a result, we end up with a property defined as {type: mongodb.ObjectID, mongodb: {dataType: 'ObjectID'}}, which is something we were not handling well before my pull request.

@bajtos bajtos merged commit 3cde61d into master Nov 22, 2019
@delete-merged-branch delete-merged-branch bot deleted the fix/detect-objectid-from-db branch November 22, 2019 08:29
@agnes512
Copy link
Contributor

To be honest, I find it difficult to understand the values in table cells. What does it mean when the value is T, F or unknown?

In order to keep it short I use short terms. T for true and F for false.
For example, when strictObjectIDCoercion sets to true and dataType: ObjectID is defined ( the top right case), it is true that it can be created with ObjectId.

I think that my pull request should not be changing the behavior

The top right case was supposed to be true, but we didn't have a test case, and it was a bug. I think your PR fix it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants