Loopback: Validation problem when patching a model with embedded relation

Created on 20 Mar 2017  路  21Comments  路  Source: strongloop/loopback

@ahallez commented on Sat Feb 04 2017

I have a model that includes an embedded relation (embedsMany).
The embedded model has auto generated ids.

When patching the parent model I get a validation error, saying the embedded model data shouldn't have it id's set.

Details of the models and patch below.

Is this a bug or do I have to change something to the configuration to prevent this?

The model json of the parent model

{
  "name": "embedTest",
  "plural": "embedTests",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "name": {
      "type": "String",
      "required": true
    }
  },
  "validations": [],
  "relations": {
    "embedded": {
      "type": "embedsMany",
      "model": "embeddedTest",
      "property": "embeddedList",
      "default": [],
      "options": {
        "validate": true,
        "forceId": true,
        "autoId": true
      }
    }
  },
  "acls": [],
  "methods": {}
}

The model json of the embedded model

{
  "name": "embeddedTest",
  "plural": "embeddedTests",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "text": {
      "type": "String",
      "required": true
    }
  },
  "validations": [],
  "relations": {
    "embedded2": {
      "type": "embedsMany",
      "model": "embedded2Test",
      "property": "embeddedList2",
      "default": [],
      "options": {
        "validate": true,
        "forceId": true,
        "autoId": true
      }
    }
  },
  "acls": [],
  "methods": {}
}

The json data of the object being patched:

{
  "name": "test",
  "id": "0f6b3ca3cc97bc15c5fd8819f000395d",
  "embeddedList": [
    {
      "text": "test",
      "id": "bdddaf6db953b988d21f021f",
      "embeddedList2": []
    }
  ],
  "_rev": "4-b177733e7ca2b2dd501f9f83662391c9"
}
````

The call made to patch the object (through the explorer interface):

curl -X PATCH --header "Content-Type: application/json" --header "Accept: application/json" -d "{
\"name\": \"new name\"
}" "http://localhost:8080/api/embedTests/0f6b3ca3cc97bc15c5fd8819f000395d"


The error message returned:

{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "De instance embedTest is niet geldig. Details: embeddedList contains invalid item: bdddaf6db953b988d21f021f (id can't be set) (value: [ { text: 'test',\n id:...} ]).",
"details": {
"context": "embedTest",
"codes": {
"embeddedList": [
"invalid"
]
},
"messages": {
"embeddedList": [
"contains invalid item: bdddaf6db953b988d21f021f (id can't be set)"
]
}
}
}
}
```

Edit:
I changed the options of the embedsMany relation to disable validation and then it works fine.
Still not clear to me if this is the way it should be. The documentation doesn't really go into detail about the use of the options on an embedded relation.


@crandmck commented on Mon Feb 06 2017

@superkhau I'm not sure if this is just a doc issue or if there's an underlying s/w problem.

There's an existing doc issue on "embedsMany" https://github.com/strongloop/loopback-datasource-juggler/issues/1174.


@superkhau commented on Tue Feb 07 2017

@crandmck I'm not sure off the top of my head, will have to try it out to verify the current behaviour. That said, @kjdelisle I'll leave this to you to triage.


@AhsanAyaz commented on Wed Mar 15 2017

+1.
I just tried to add a second embedsMany relation and it is breaking the same way.
I.e.

{ "error": { "statusCode": 422, "name": "ValidationError", "message": "TheLexiconinstance is not valid. Details:_keywordscontains invalid item:58c900f3e1a7e26023eab0e3(idcan't be set) (value: [ ......


@crandmck commented on Wed Mar 15 2017

@bajtos Can you say if this is a doc issue or if there's a bug?


@bajtos commented on Mon Mar 20 2017

IIUC, this problem is cause by forceId model setting which changed the default value from false to true in LoopBack 3.0.

Now the question is, what is the correct setup of the id property for embedded relations? Should embedded items have any id at all?

If they do, then we should keep forceId:true, in order to prevent DoS attacks where e.g. the client can submit the maximum integer value supported by the backing database as the id value, and thus preventing any further instance to be created, because the database cannot auto-increment beyond the maximum integer value.

forceId check is triggered only when the model instance is considered as "new". I think we need to fix the implementation of our embedded relations so that it marks embedded model instances as "not new" by passing {persisted: true} in the options of model constructor and/or _initProperties. Examples:

In that light, I think this isue should be labelled as a bug.


@crandmck commented on Mon Mar 20 2017

I think we need to fix the implementation of our embedded relations

OK, since this is not a doc issue, but rather a bug, I'm going to move this from loopback.io repo to loopback.

bug stale

Most helpful comment

i think this will help you , just add
"id": {
"type": "string",
"id": true,
"defaultFn": "uuid"
}
to your embedded model properties , that's help me

All 21 comments

Workaround is only making validate false. Any update on this?

I'm running the exact issue by turning forceId=true. Turning validation false worries me. Any update on this? Thanks!

+1
Ran into same problem

+1
Same issue here too

@bajtos Is setting validate=false the only viable solution for now here? Seems to be the only thing that works for me (and others from the sounds of it).

+1
Same issue here too

+1
Same issue here too

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.

this issue still occurs, anyone has the answer for this?

No solution for this error yet?

@israelglar I gave up and rewrite the CRUD on my own. I nested the object and validate with joi instead of using embedded relation.

@jura-b That's sad :/ But thanks for the reply

Any news about this bug ?

Any update on this bug ?

i think this will help you , just add
"id": {
"type": "string",
"id": true,
"defaultFn": "uuid"
}
to your embedded model properties , that's help me

@everyone please try @maherzaidoune 's suggestion(Thank you Maher!) and see if it solves your problem.

Allow me some time to reproduce the error if it's still not fixed. I will make a PR for it.

Have same prob here. Can't solve this :-(

@maherzaidoune worked perfectly, you need to set "idInjection": false in your embedded model also. and leave "forceId": false as is.

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.

Was this page helpful?
0 / 5 - 0 ratings