objection.js
objection.js copied to clipboard
patch validator fails on JSON column updates when jsonSchema contains additionalProperties:false
static get jsonSchema() {
return {
type: 'object',
additionalProperties: false,
properties: {
id: { type: 'integer' },
meta: {
type: 'object',
additionalProperties: false,
properties: {
a: { type: 'string' },
b: { type: 'string' }
}
}
}
};
}
Trying to .patch({ "meta:b": "foo" })
results in the error "ValidationError: meta:b: is an invalid additional property"
I monkey-patched modelSet.js setJson function to iterate over the references and turn that into:
{ meta: { b: "foo" } }
to get it to work, but I wasn't certain if that was the proper location to make that change, so I didn't submit a PR yet.
My code is below for how I was able to resolve it temporarily locally:
-- modelSet.js
function setJson(model, json, options) {
...
// BEGIN: ADDED
const { ref } = require('../queryBuilder/ReferenceBuilder');
for (const key of Object.keys(json)) {
let val = json[key];
if (key.indexOf(':') > -1) {
// 'jsonColumn:attr' : 123 is transformed to { jsonColumn: { attr: 123 } }
let parsed = ref(key);
let jsonRef = parsed.parsedExpr.access[0].ref;
if (json[parsed.column] === undefined) {
json[parsed.column] = {};
}
json[parsed.column][jsonRef] = val;
delete json[key];
}
}
// END: ADDED
json = model.$parseJson(json, options);
...
Thoughts?
I've always cosidered using additionalProperties: false
pretty useless with model classes. I've always preferred using removeAdditional instead.
Thanks for the tip. I was able to get it working by specifying options.removeAdditional:true in createValidator.
However, I'd rather receive a validation error (especially for JSON database columns) rather than have the extra keys removed and not end up in the database.
Until this is resolved, to achieve the desired behavior, It looks like I'm going to have to .fetch() -> merge objects -> use .update() instead of simply .patch() for my Models containing JSON columns. Not a big deal, I was just trying to reduce queries by using patch here.