Nodal Server Crashes if Joined Table Field Name Matches Model Name
nsipplswezey opened this issue · comments
TL;DR
If your model is called Tweet
, and your endpoint is called tweets
and one of your model fields is called tweets
and you join Tweet
to another model, like User
, Nodal will crash on any requests to your tweet endpoint.
Simplest solution is to tell users not to do this.
Simple solution 1 is to validate field names in nodal g:model name1:type name2:type
against endpoints and model names.
Simple solution 2 is to add feedback to the error handling block in __setJoined__
which handles this error:
nodal/core/required/model.js:706:17
Simple solution 3 is to figure out why this naming/reference conflict between model field names and API endpoints happens exactly, and address that. My intuition suggests that it has something to do with how URLs are parsed, or how the parsed output is consumed. But honestly that's just a guess.
Practical Use Case: I had a Todo model, with a json field named todos
, which was used to store an array of client todo objects.
todos
was a natural name for a field containing a json array of todos
To recreate:
nodal g:model Tweet user_id:int tweets:string
nodal g:model --user
nodal g:controller --for Tweet
nodal g:controller --for User
Go to your tweet model, import your User model and Tweet.joinsTo(User,{multiple:true})
Try POST to /tweets with something like user_id=1
and tweets=hello
Try GET to /tweets
Nodal server will throw the following error on a POST to /tweets/
with user_id=1
and tweets=hello
{
"meta": {
"total": 0,
"count": 0,
"offset": 0,
"error": {
"message": "Internal Server Error",
"details": [
"Error: hello is not an instance of User",
" at Tweet.setJoined (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:706:17)",
" at Tweet.__safeSet__ (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:507:21)",
" at /Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:456:14",
" at Array.forEach (native)",
" at Tweet.__load__ (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:455:12)",
" at Tweet.Model (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:34:12)",
" at Tweet (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/app/models/tweet.js:8:3)",
" at Function.create (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:77:19)",
" at V1TweetsController.create (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/app/controllers/v1/tweets_controller.js:34:13)",
" at /Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/controller.js:59:63"
]
}
},
"data": []
}
And the following on a GET
{
"meta": {
"total": 0,
"count": 0,
"offset": 0,
"error": {
"message": "Internal Server Error",
"details": [
"Error: hello is not an instance of User",
" at Tweet.setJoined (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:706:17)",
" at Tweet.__safeSet__ (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:507:21)",
" at /Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:456:14",
" at Array.forEach (native)",
" at Tweet.__load__ (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:455:12)",
" at Tweet.Model (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/model.js:34:12)",
" at Tweet (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/app/models/tweet.js:8:3)",
" at /Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/composer.js:108:39",
" at Array.forEach (native)",
" at Composer.__parseModelsFromRows__ (/Users/nsipplsw/nodal-doc-release/nodal/examples/model-matches-field-name-bug/node_modules/nodal/core/required/composer.js:102:12)"
]
}
},
"data": []
}
Going to close this right now. Just don't name field names the same as the model. It generally doesn't make sense to do, anyway.