{"action":"created","issue":{"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/1321","repository_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler","labels_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/1321/labels{/name}","comments_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/1321/comments","events_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/1321/events","html_url":"https://github.com/strongloop/loopback-datasource-juggler/issues/1321","id":220464461,"number":1321,"title":"Issues with `validatesUniquenessOf`","user":{"login":"emilio-martinez","id":9163179,"avatar_url":"https://avatars0.githubusercontent.com/u/9163179?v=4","gravatar_id":"","url":"https://api.github.com/users/emilio-martinez","html_url":"https://github.com/emilio-martinez","followers_url":"https://api.github.com/users/emilio-martinez/followers","following_url":"https://api.github.com/users/emilio-martinez/following{/other_user}","gists_url":"https://api.github.com/users/emilio-martinez/gists{/gist_id}","starred_url":"https://api.github.com/users/emilio-martinez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emilio-martinez/subscriptions","organizations_url":"https://api.github.com/users/emilio-martinez/orgs","repos_url":"https://api.github.com/users/emilio-martinez/repos","events_url":"https://api.github.com/users/emilio-martinez/events{/privacy}","received_events_url":"https://api.github.com/users/emilio-martinez/received_events","type":"User","site_admin":false},"labels":[{"id":40062716,"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/labels/bug","name":"bug","color":"e99695","default":true},{"id":479880847,"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/labels/committed","name":"committed","color":"eeeeee","default":false},{"id":640670920,"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/labels/team-apex","name":"team-apex","color":"fef2c0","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/milestones/92","html_url":"https://github.com/strongloop/loopback-datasource-juggler/milestone/92","labels_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/milestones/92/labels","id":2714121,"number":92,"title":"Sprint 43 - Apex","description":"Team Apex Sprint Milestone","creator":{"login":"kjdelisle","id":2053534,"avatar_url":"https://avatars3.githubusercontent.com/u/2053534?v=4","gravatar_id":"","url":"https://api.github.com/users/kjdelisle","html_url":"https://github.com/kjdelisle","followers_url":"https://api.github.com/users/kjdelisle/followers","following_url":"https://api.github.com/users/kjdelisle/following{/other_user}","gists_url":"https://api.github.com/users/kjdelisle/gists{/gist_id}","starred_url":"https://api.github.com/users/kjdelisle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kjdelisle/subscriptions","organizations_url":"https://api.github.com/users/kjdelisle/orgs","repos_url":"https://api.github.com/users/kjdelisle/repos","events_url":"https://api.github.com/users/kjdelisle/events{/privacy}","received_events_url":"https://api.github.com/users/kjdelisle/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":4,"state":"open","created_at":"2017-08-21T18:30:10Z","updated_at":"2017-08-24T01:03:41Z","due_on":"2017-09-04T07:00:00Z","closed_at":null},"comments":0,"created_at":"2017-04-09T11:13:40Z","updated_at":"2017-08-25T15:16:24Z","closed_at":null,"body":"# Description/Steps to reproduce\r\n**Bug**\r\nCombining `findOrCreate` with `validatesUniquenessOf` results in failure after the first time.\r\nhttps://github.com/emilio-martinez/loopbackValidatesUniquenessOfIssue\r\n\r\n# Expected result\r\nThe expectation is that because the attempted operation involves finding OR creating, no validation should be required when there is a value to be found. However, even if there is, it seems that `validatesUniquenessOf` attempts validation despite the availability of an item that meets the filter parameters.\r\n\r\nThis is additionally more problematic with a `required` property because, for example, if we try to remove the property to work around the uniqueness issue—for example, on a `before save` operation hook—then we're faced with another validation error: `presence`.\r\n\r\nIt's a \"catch 22\". The same issues can be found on other operations such as `upsertWithWhere`.\r\n\r\nIn the repro code that I provided as \"Steps to reproduce\", simply run the server twice so that the boot script I created runs two times. you'll notice that the second time you'll get an error `ValidationError: The 'sample' instance is not valid. Details: 'uniqueAndRequired' is not unique (value: \"Action\")`\r\n\r\n# Additional information\r\n`darwin x64 6.9.2`\r\n```\r\n├── loopback@3.6.0\r\n├── loopback-boot@2.24.0\r\n├── loopback-component-explorer@4.2.0\r\n```"},"comment":{"url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/comments/324950825","html_url":"https://github.com/strongloop/loopback-datasource-juggler/issues/1321#issuecomment-324950825","issue_url":"https://api.github.com/repos/strongloop/loopback-datasource-juggler/issues/1321","id":324950825,"user":{"login":"ssh24","id":15173354,"avatar_url":"https://avatars3.githubusercontent.com/u/15173354?v=4","gravatar_id":"","url":"https://api.github.com/users/ssh24","html_url":"https://github.com/ssh24","followers_url":"https://api.github.com/users/ssh24/followers","following_url":"https://api.github.com/users/ssh24/following{/other_user}","gists_url":"https://api.github.com/users/ssh24/gists{/gist_id}","starred_url":"https://api.github.com/users/ssh24/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ssh24/subscriptions","organizations_url":"https://api.github.com/users/ssh24/orgs","repos_url":"https://api.github.com/users/ssh24/repos","events_url":"https://api.github.com/users/ssh24/events{/privacy}","received_events_url":"https://api.github.com/users/ssh24/received_events","type":"User","site_admin":false},"created_at":"2017-08-25T15:16:24Z","updated_at":"2017-08-25T15:16:24Z","body":"The main issue here persists in the base `findOrCreate` function in `dao.js`.\r\nhttps://github.com/strongloop/loopback-datasource-juggler/blob/6c6df15286400e0dfbc2a458e0a074acc1abeecd/lib/dao.js#L1054-L1251\r\n\r\nIt has nothing to do with the `validatesUniquenessOf` rule and instead all types of validation rule would cause this issue. I suggest whoever taking on this task to write exhaustive test cases on each of the [validation rules](https://apidocs.strongloop.com/loopback-datasource-juggler/#validatable).\r\n\r\nBefore showing an example, I would like to make it clear the definition of `findOrCreate` function. It literally means what it is called, **if an instance exists with the given query, return that instance, and if it does not, create an instance with the given data**.\r\n\r\nFor example:\r\n\r\nIf I have the following model instances\r\n\r\n```json\r\ninst1: {\r\n  \"id\": 1,\r\n  \"name\": \"foo\",\r\n  \"age\": 12\r\n}\r\n```\r\n\r\n```json\r\ninst2: {\r\n  \"id\": 2,\r\n  \"name\": \"bar\",\r\n  \"age\": 15\r\n}\r\n```\r\n\r\n```json\r\ninst3: {\r\n  \"id\": 3,\r\n  \"name\": \"baz\",\r\n  \"age\": 20\r\n}\r\n```\r\n\r\nAnd I set a validation rule `Model.validatesUniquenessOf('id');`\r\n\r\nAfter if I perform a `findOrCreate` call eg. \r\n```js\r\nfindOrCreate({\"where\": {\"id\": 1}}, {\"id\": 1, \"name\": \"foo-new\"}, cb);\r\n```\r\n\r\nThis would throw the validation error even before trying to find the instance. Look at this [line](https://github.com/strongloop/loopback-datasource-juggler/blob/6c6df15286400e0dfbc2a458e0a074acc1abeecd/lib/dao.js#L1223). IMO, the function needs to be refactored so that it:\r\n```\r\n1. tries to find the instance with the query\r\n2. if an instance is found return that instance\r\n3. if it does not exist, validate the instance to be created\r\n4. if validation succeeds, create the instance\r\n5. if the validation fails, throw the validation error\r\n```"}}
{"actor":{"display_login":"ssh24"}}