-
Notifications
You must be signed in to change notification settings - Fork 643
Description
In my application I an overriding objection.Model's $formatJson() method in order to strip out certain fields from my models before they are sent based on user permissions, etc. This typically works out great.
I'm running into problems when inserting a model via insertWithRelated(). I've noticed that $formatJson() is being called on the data before it is inserted into the database so my protected fields are being striped out before being saved.
Here is a demo I put together:
const objection = require('objection');
const knex = require('knex');
const Model = objection.Model;
const db = knex({
client: 'mysql2',
connection: "mysql://event_planner:123456ab@localhost/event_planner",
pool: {
min: 2,
max: 30
}
});
Model.knex(db);
class Employee extends Model {
static get tableName() {
return 'employees';
}
static get relationMappings() {
return {
organization: {
relation: Model.BelongsToOneRelation,
modelClass: Organization,
join: {
from: 'employees.organizationId',
to: 'organizations.id'
}
}
};
}
$beforeInsert() {
console.log('$beforeInsert', this.constructor.tableName);
}
$beforeUpdate() {
console.log('$beforeUpdate', this.constructor.tableName);
}
$formatJson(json) {
console.log('$formatJson', this.constructor.tableName);
json = super.$formatJson(json);
json.firstName = undefined;
return json;
}
$parseJson(json, opt) {
console.log('$parseJson', this.constructor.tableName, json, opt);
return super.$parseJson(json, opt);
}
}
class Organization extends Model {
static get tableName() {
return 'organizations';
}
static get relationMappings() {
return {
employees: {
relation: Model.HasManyRelation,
modelClass: Employee,
join: {
from: 'organizations.id',
to: 'employees.organizationId'
}
}
};
}
$beforeInsert() {
console.log('$beforeInsert', this.constructor.tableName);
}
$beforeUpdate() {
console.log('$beforeUpdate', this.constructor.tableName);
}
$formatJson(json) {
console.log('$formatJson', this.constructor.tableName);
return super.$formatJson(json);
}
$parseJson(json, opt) {
console.log('$parseJson', this.constructor.tableName, opt);
return super.$parseJson(json, opt);
}
}
Organization
.query()
.allowInsert('[employees]')
.insertWithRelated({
name: "My Organization",
employees: [{
firstName: "John",
lastName: "Doe",
email: "doe@example.com"
}]
}).catch(err => console.error(err));the above prints the following to the console:
$parseJson organizations { skipValidation: true }
$parseJson employees { firstName: 'John',
lastName: 'Doe',
email: 'doe@example.com',
phone: '[]',
streetAddress: '',
notes: '',
createdAt: 2017-03-12T01:13:18.697Z,
updatedAt: 2017-03-12T01:13:18.697Z } { skipValidation: true }
$formatJson organizations
$parseJson organizations undefined
$beforeInsert organizations
$formatJson employees
$parseJson employees { firstName: undefined,
lastName: 'Doe',
email: 'doe@example.com',
phone: '[]',
streetAddress: '',
notes: '',
createdAt: 2017-03-12T01:13:18.697Z,
updatedAt: 2017-03-12T01:13:18.697Z,
organizationId: 156 } undefined
$beforeInsert employees
Is this behavior intended? The docs mention that $formatJson() is for converting the model from its 'internal' to 'external' format. Everything happening during an insert is 'internal' so I feel like $formatJson() shouldn't be called at all here.