ValidationError: field must be object but the schema types is already set into object
fs-arman opened this issue · comments
I have a column augmentedTerms
and result
both are jsonb in my Postgres.
This augmentedTerms
contains an array of strings while
result
contains an array of objects.
When I do patch, I got this error:
ValidationError: augmentedTerms: must be object, result: must be object
But the weird thing is that I already set there types into object. (Refer the searchAudit schema below)
Any idea what's wrong? Is this a bug in objection js?
Thanks!
I'm using objection v3.0.1
Expected save data in postgres DB:
id |terms |results |augmented_terms |
---+-----------------+-----------------------------------------------------+-------------------+
153|Drafting Services|[799, 62, 659, 660, 678, 685, 686, 703, 718, 722] |["draft", "servic"]|
154|Engineering |[116, 669, 2460, 797, 802, 1049, 2382, 118, 767, 880]|["engineer"] |
/**
* This is a simple template for bug reproductions. It contains three models `Person`, `Animal` and `Movie`.
* They create a simple IMDB-style database. Try to add minimal modifications to this file to reproduce
* your bug.
*
* install:
* npm install objection knex sqlite3 chai
*
* run:
* node reproduction-template
*/
let Model;
Model = require('objection').Model;
const Knex = require('knex');
async function main() {
await createSchema();
///////////////////////////////////////////////////////////////
// Your reproduction
///////////////////////////////////////////////////////////////
let searchString = 'Honda'
let terms = ['car', 'transpo']
let allClassIds = [
{"id":798,"incClassId":1798,"title":"Engineering Services"},
{"id":799,"incClassId":2798,"title":"Drafting Services"}
]
let auditEntry = {
id: 136,
terms: searchString,
augmentedTerms: JSON.stringify(terms),
result: JSON.stringify(allClassIds.map(({ id }) => id))
}
console.log('auditEntry:', auditEntry)
return await searchAudit.query().patch(auditEntry).catch(e => {
console.log(`Unable to update: ${auditEntry}`)
console.log(e)
})
}
///////////////////////////////////////////////////////////////
// Database
///////////////////////////////////////////////////////////////
const knex = Knex({
client: 'sqlite3',
useNullAsDefault: true,
debug: false,
connection: {
filename: ':memory:'
}
});
Model.knex(knex);
///////////////////////////////////////////////////////////////
// Models
///////////////////////////////////////////////////////////////
class searchAudit extends Model {
static get tableName () {
return 'searchAudit'
}
static get jsonSchema () {
return {
type: 'object',
properties: {
id: { type: 'integer' },
terms: { type: 'string' },
augmentedTerms: { type: 'object' },
result: { type: 'object' }
}
}
}
}
///////////////////////////////////////////////////////////////
// Schema
///////////////////////////////////////////////////////////////
async function createSchema() {
await knex.schema
.dropTableIfExists('searchAudit')
await knex.schema
.createTable('searchAudit', table => {
table.increments('id').primary();
table.string('terms');
table.jsonb('result');
table.jsonb('augmentedTerms');
});
}
main()
.then(() => {
console.log('success');
return knex.destroy();
})
.catch(err => {
console.error(err);
return knex.destroy();
});
You're stringifying the fields augmentedTerms
and result
here:
let auditEntry = {
id: 136,
terms: searchString,
augmentedTerms: JSON.stringify(terms),
result: JSON.stringify(allClassIds.map(({ id }) => id))
}
After that, they're strings, not objects. The validation is correct in complaining about it. Remove the calls of JSON.stringify()
and you should be all set.