-
Notifications
You must be signed in to change notification settings - Fork 365
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
hasMany through doesn't set the through key value #394
hasMany through doesn't set the through key value #394
Conversation
Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test." |
I did a little digging, I'm guessing the Logging the keys returned from within the add function shows the wrong set returned. |
There seems to be a bug in handling multiple belongsTo relations to the same model, see: |
I'm facing this problem (or a related one) with loopback-datasource-juggler 2.14.1, too. I have the following models: {
"name": "Customuser",
"base": "User",
"properties": {
.....
},
"relations": {
"supportingUsers": {
"type": "hasMany",
"model": "Customuser",
"through": "SupporterMapping",
"foreignKey": "supportingUserId"
},
"supportedUsers": {
"type": "hasMany",
"model": "Customuser",
"through": "SupporterMapping",
"foreignKey": "supportedUserId"
},
"supportedSites": {
"type": "hasMany",
"model": "Site",
"through": "SupporterMapping",
"foreignKey": "supportedSiteId"
},
},
...
} {
"name": "Site",
"base": "PersistedModel",
"properties": {
...
},
"relations": {
"customer": {
"type": "belongsTo",
"model": "Customuser",
"foreignKey": "customerId"
},
"siteSupporter": {
"type": "hasMany",
"model": "Customuser",
"through": "SupporterMapping",
"foreignKey": "supportingUserId"
}
},
...
} {
"name": "SupporterMapping",
"base": "PersistedModel",
"properties": {
...
},
"relations": {
"supportingUser": {
"type": "belongsTo",
"model": "Customuser"
},
"supportedUser": {
"type": "belongsTo",
"model": "Customuser"
},
"supportedSite": {
"type": "belongsTo",
"model": "Site"
}
},
...
} IMHO, relations are set up correctly. Querying the model SupporterMapping using the StrongLoop API Explorer resolves all relations correctly. But errors arise for the following API methods: {
"error": {
"name": "Error",
"status": 500,
"message": "Relation \"site\" is not defined for SupporterMapping model",
"stack": "Error: Relation \"site\" is not defined for SupporterMapping model\n at processIncludeItem (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:144:10)\n at c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:118:5\n at c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:125:13\n at Array.forEach (native)\n at _each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:46:24)\n at Object.async.each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:124:9)\n at Function.Inclusion.include (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:117:9)\n at MySQL.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:588:33)\n at releaseConnectionAndCallback (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:149:17)\n at Query.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:163:7)"
}
} GET /Hoocusers/{id}/supportedUsers {
"error": {
"name": "Error",
"status": 500,
"message": "Relation \"customuser\" is not defined for SupporterMapping model",
"stack": "Error: Relation \"customuser\" is not defined for SupporterMapping model\n at processIncludeItem (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:144:10)\n at c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:118:5\n at c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:125:13\n at Array.forEach (native)\n at _each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:46:24)\n at Object.async.each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:124:9)\n at Function.Inclusion.include (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:117:9)\n at MySQL.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:588:33)\n at releaseConnectionAndCallback (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:149:17)\n at Query.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:163:7)"
}
} GET /Hoocusers/{id}/supportingUsers {
"error": {
"name": "Error",
"status": 500,
"message": "Relation \"customuser\" is not defined for SupporterMapping model",
"stack": "Error: Relation \"customuser\" is not defined for SupporterMapping model\n at processIncludeItem (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:144:10)\n at c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:118:5\n at c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:125:13\n at Array.forEach (native)\n at _each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:46:24)\n at Object.async.each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:124:9)\n at Function.Inclusion.include (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:117:9)\n at MySQL.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:588:33)\n at releaseConnectionAndCallback (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:149:17)\n at Query.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:163:7)"
}
} GET /Sites/{id}/siteSupporter {
"error": {
"name": "Error",
"status": 500,
"message": "Relation \"customuser\" is not defined for SupporterMapping model",
"stack": "Error: Relation \"customuser\" is not defined for SupporterMapping model\n at processIncludeItem (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:144:10)\n at c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:118:5\n at c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:125:13\n at Array.forEach (native)\n at _each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:46:24)\n at Object.async.each (c:\\hfb_webapp\\node_modules\\async\\lib\\async.js:124:9)\n at Function.Inclusion.include (c:\\hfb_webapp\\node_modules\\loopback-datasource-juggler\\lib\\include.js:117:9)\n at MySQL.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:588:33)\n at releaseConnectionAndCallback (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:149:17)\n at Query.<anonymous> (c:\\hfb_webapp\\node_modules\\loopback-connector-mysql\\lib\\mysql.js:163:7)"
}
} So far, I was able to track down the problem to this section where Hopefully, this is helpful for you. Thanks for your excellent work! |
Here's my solution so far: (code not ready for check-in) |
@clarkbw Pls let us know when your patch is ready to merge. |
I just want to let you know that @clarkbw's patch is working for me. Furthermore, I had to add the "keyThrough" property to the "hasMany" relation definitions. Unfortunately, this property is not documented anywhere and it cost me half a day digging into the code and find this solution. Enhance the docs accordingly, please. But now, my models work now as expected. Here my modified model definitions. Hopefully, someone can benefit from them: {
"name": "Customuser",
"base": "User",
"properties": {
.....
},
"relations": {
"supportingUsers": {
"type": "hasMany",
"model": "Hoocuser",
"through": "SupporterMapping",
"foreignKey": "supportedUserId",
"keyThrough": "supportingUserId"
},
"supportedUsers": {
"type": "hasMany",
"model": "Hoocuser",
"through": "SupporterMapping",
"foreignKey": "supportingUserId",
"keyThrough": "supportedUserId"
},
"supportedSites": {
"type": "hasMany",
"model": "Site",
"through": "SupporterMapping",
"foreignKey": "supportingUserId",
"keyThrough": "supportedSiteId"
},
},
...
} {
"name": "Site",
"base": "PersistedModel",
"properties": {
...
},
"relations": {
"customer": {
"type": "belongsTo",
"model": "Customuser",
"foreignKey": "customerId"
},
"siteSupporters": {
"type": "hasMany",
"model": "Hoocuser",
"through": "SupporterMapping",
"foreignKey": "supportedSiteId",
"keyThrough": "supportingUserId"
}
},
...
} {
"name": "SupporterMapping",
"base": "PersistedModel",
"properties": {
...
},
"relations": {
"supportingUser": {
"type": "belongsTo",
"model": "Customuser"
},
"supportedUser": {
"type": "belongsTo",
"model": "Customuser"
},
"supportedSite": {
"type": "belongsTo",
"model": "Site"
}
},
...
} |
@raymondfeng let me know if including lodash-node is ok. I can make it work either way; I prefer using lodash but I'm not sure what the project guidelines are for module inclusion. |
lodash is fine. |
@raymondfeng updated, rebased against master and squashed into 1 commit. I'm probably going to continue to be slow on the turnaround time but let me know if you want any changes. |
ok to test |
@clarkbw Have you signed the CLA - https://cla.strongloop.com/agreements/strongloop/loopback-datasource-juggler? |
Sorry. I thought I did, but I'm wondering now if I signed it for loopback and not this module if they are different CLAs. Signed again, I'll look into the build failures. |
@clarkbw Any update on the test failures? |
Looking through them now, I wasn't seeing those previously so I'll have to track down the change that made the difference. |
@raymondfeng updated and passing. |
hasMany through doesn't set the through key value
@steirico I have the same problem as you, but your synthax did not worked for me. |
@clarkbw I use the same configuration than you. (working, defs contains what I want) app.models.Definition.findOne { where: { external_id: '19A35136542D582B' }, include: ['referencedDefinitions']}, (err, def) ->
assert.equal err, null
defs = def.referencedDefinitions() (not working, defs contains doublons or even all data) app.models.Definition.findOne { where: { external_id: '19A35136542D582B' }, include: ['referencedDefinitions'], fields:['referencedDefinitions']}, (err, def) ->
assert.equal err, null
defs = def.referencedDefinitions() |
I created a quick test to describe the hasManyThrough issue I'm seeing. I left in the console.log call so you can easily see the problematic object. (pull in my PR and run npm test)
followerId
is being set but thefolloweeId
attribute is not set; a critical piece when creating this object. This test demonstrates using theadd
function though I haven't testing with other relation functions like create.