I'm setting up simple API using Postgresql
, Knex.j
s and Objection.js
. I created User model with "location" property. This "location" property is another table. How I have to insert that user to database with defaults 'city' and 'country' in 'location' property?
I already tried to use 'static get jsonSchema
' in model itself and 'allowInsert
' method in mutation but when I fetching created that user the 'location' still 'null'.
So, let's say we have migration for users_table:
exports.up = knex =>
knex.schema.createTable('users', table => {
table.increments('id').primary();
table
.string('email')
.unique()
.notNullable();
table.string('firstName').notNullable();
table.string('lastName').notNullable();
table.string('password').notNullable();
});
exports.down = knex => knex.schema.dropTable('users');
And we have location_table:
exports.up = knex =>
knex.schema.createTable('locations', table => {
table.increments('id').primary();
table.string('country').defaultTo('USA');
table.string('city').defaultTo('San Francisco');
table
.integer('user_id')
.references('id')
.inTable('users')
.onUpdate('CASCADE')
.onDelete('CASCADE');
});
exports.down = knex => knex.schema.dropTable('locations');
Here User Model with objection.js:
export default class User extends Model {
static get tableName() {
return 'users';
}
// wrong probably
static get jsonSchema() {
return {
type: 'object',
properties: {
location: {
type: 'object',
properties: {
city: {
type: 'string',
default: 'Los Angeles',
},
country: {
type: 'string',
default: 'USA',
},
},
},
},
};
}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
static get relationMappings() {
return {
location: {
relation: Model.HasOneRelation,
modelClass: Location,
join: {
from: 'users.id',
to: 'locations.user_id',
},
},
};
}
}
And Location model:
export default class Location extends Model {
static get tableName() {
return 'locations';
}
static get relationMappings() {
return {
user: {
relation: Model.BelongsToOneRelation,
modelClass: `${__dirname}/User`,
join: {
from: 'locations.user_id',
to: 'users.id',
},
},
};
}
}
My mutation when I creating new User:
// ...
const payload = {
email,
firstName,
lastName,
password: hash,
};
const newUser = await User.query()
.allowInsert('[user, location]')
.insertAndFetch(payload);
// ...
And in the end query:
// ...
User.query()
.eager('location')
.findOne({ email });
// ...
From query of user I expect to see the object with locatoin propety with my defaults. Example:
{
email: 'jacklondon@gmail.com',
firstName: 'Jack',
fullName: 'Jack London',
id: '1',
lastName: 'London',
location: {
city: 'San Francisco',
country: 'USA',
},
userName: 'jacklondon1',
__typename: 'User',
}
So, where I made mistake with such simple operation?