When I associate a model with embedsOne, if I create it through the POST /api/model/:id/embeddedModel automatically the id is generated despite the explicit forceId field with the value false.
This is my setup:
{
"name": "Culture",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"tag": {
"type": "string",
"required": true
},
...
},
"validations": [],
"relations": {
"dateTime": {
"type": "embedsOne",
"model": "IntlDateTimeFormat",
"property": "dateTimeFormat",
"options": {
"validate": false,
"forceId": false
}
}
}
...
}
{
"name": "IntlDateTimeFormat",
"base": "Model",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"calendar": {
"type": "string"
},
...
},
...
}
While as regards the embedsMany, despite I set forceId to true, if I not insert the id in the object, a duplicate id error is returned:
{
"error": {
"name": "ValidationError",
"status": 422,
"message": "The `Member` instance is not valid. Details: `emailList` contains duplicate `id` (value: [ { label: 'mail1', email: ...} ]).",
"statusCode": 422,
"details": {
"context": "Member",
"codes": {
"emailList": [
"uniqueness"
]
},
"messages": {
"emailList": [
"contains duplicate `id`"
]
}
},
"stack": "ValidationError: The `Member` instance is not valid. Details: `emailList` contains duplicate `id` (value: [ { label: 'mail1', email: ...} ]).\n at /Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/dao.js:317:12\n at ModelConstructor.<anonymous> (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/validations.js:487:13)\n at ModelConstructor.next (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/hooks.js:75:12)\n at done (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/validations.js:484:25)\n at /Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/validations.js:558:7\n at ModelConstructor.<anonymous> (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/validations.js:357:5)\n at /Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/dao.js:1561:9\n at Object.async.each (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/node_modules/async/lib/async.js:153:20)\n at allCb (/Users/lughino/Projects/test-server/api/node_modules/loopback-datasource-juggler/lib/dao.js:1497:13)\n at /Users/lughino/Projects/test-server/api/node_modules/loopback-connector-mongodb/lib/mongodb.js:753:9"
}
}
This is the configuration:
{
"name": "Member",
"base": "User",
"strict": false,
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string"
},
...
},
"validations": [],
"relations": {
"emailAddresses": {
"type": "embedsMany",
"model": "EmailAddress",
"property": "emailList",
"options": {
"validate": true,
"forceId": true
}
}
},
...
}
{
"name": "EmailAddress",
"base": "Model",
"idInjection": true,
"properties": {
"label": {
"type": "string"
},
"email": {
"type": "string",
"required": true
}
},
...
}
is there an update for this issue? I'm seeing the same behavior. I debugged the code to this statement in relation-definition.js:
var assignId = (forceId || targetModelData[pk] === undefined);
assignId = assignId && !persistent && (pkProp && pkProp.generated);
where forceId=false, pk is set to "id", pkProp is an object and pkProp.generated is true. It seems that maybe overwriting the primary key properties will achieve the desired behavior of not assigning an id. thoughts?
This does seem to conflict with the documentation, https://docs.strongloop.com/display/public/LB/Model+definition+JSON+file#ModeldefinitionJSONfile-IDproperties.
By default, if no ID properties are defined and the idInjection property is true (or is not set, since true is the default), LoopBack automatically adds an id property to the model
fyi ... the forceId behavior is explained a bit in a comment on a separate issue: https://github.com/strongloop/loopback/issues/556#issuecomment-55234224
When I first saw it, I assumed it to be a flag which when true would force the embedded model to have an id. That's not the correct understanding. It determines whether or not you allow the user to set the "id" property. Setting it to true means the user is not able to override the system generated id, a false value means the user may supply a value for the property and it will be accepted.
Well, that's true until I add "persistent": true at which point the value of "forceId" appears to be ignored and the "id" will be set with the user's value.
@Lughino Do you want to exclude 'id' property from IntlDateTimeFormat model? We have recently added 'excludeBaseProperties' capability to exclude property inherited from base model automatically, for e.g in this case 'id'. Can you try with the latest loopback code by adding 'excludeBaseProperties' to your model like below?
{
"name": "IntlDateTimeFormat",
"base": "Model",
"idInjection": false,
"forceId": "false",
"excludeBaseProperties": [
"id"
],
"options": {
"validateUpsert": true
},
"properties": {
"calendar": {
"type": "string"
},
...
},
...
}
@tjosbon there seems to be some conflicted opinions on what forceId does in the docs:
Here, it says
forceId - force generation of ida for embedded items, default to false
And here its says, as you report
If true, prevents clients from setting the auto-generated ID value manually.
Sorry, just noticed that you already highlighted the doc issue.
Same issue :(
facing the same problem... any workaround? these injected ids make validations in other parts of my application fail
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Any update yet?
Same Issue
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Why there's no assignee here 馃?
Bump
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.