From 6894ea0867b315aa6acee8b025c1961f9c6d2012 Mon Sep 17 00:00:00 2001 From: Jason Claxton <30830544+Jozzey@users.noreply.github.com> Date: Wed, 23 Nov 2022 15:16:25 +0000 Subject: [PATCH] Implement objection in water-abstraction-system (#34) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://eaflood.atlassian.net/browse/WATER-3829 Implement [Objection ORM](https://www.npmjs.com/package/objection) in `water-abstraction-system`. The time for running raw Knex queries is ending. We’ll be creating `billing_batches` and `events` soon. So, we need our chosen ORM in place to do this. --- app/models/base.model.js | 40 ++++++++++++++++++++++++ app/models/charge_version.model.js | 30 ++++++++++++++++++ app/models/licence.model.js | 38 ++++++++++++++++++++++ app/models/region.model.js | 30 ++++++++++++++++++ test/models/charge_version.model.test.js | 19 +++++++++++ test/models/licence.model.test.js | 19 +++++++++++ test/models/region.model.test.js | 19 +++++++++++ 7 files changed, 195 insertions(+) create mode 100644 app/models/base.model.js create mode 100644 app/models/charge_version.model.js create mode 100644 app/models/licence.model.js create mode 100644 app/models/region.model.js create mode 100644 test/models/charge_version.model.test.js create mode 100644 test/models/licence.model.test.js create mode 100644 test/models/region.model.test.js diff --git a/app/models/base.model.js b/app/models/base.model.js new file mode 100644 index 0000000000..c5173b3789 --- /dev/null +++ b/app/models/base.model.js @@ -0,0 +1,40 @@ +'use strict' + +/** + * @module BaseModel + */ + +const { Model } = require('objection') + +const { db } = require('../../db/db.js') + +// We only have to do this once in the app and then it will be set globally for Objection. As we are not using multiple +// databases we have no need to pass it into each query we build. And setting it here means all subclasses will inherit +// it. https://vincit.github.io/objection.js/api/model/static-methods.html#static-knex +Model.knex(db) + +class BaseModel extends Model { + /** + * An objective property we override to tell it where to search for models for relationships + * + * When setting a relationship in a model we have to provide a reference to the related model. As we need to set the + * relationship on both sides this leads to + * {@link https://vincit.github.io/objection.js/guide/relations.html#require-loops|require-loops}. We can avoid this + * by having the model tell Objection where to search for models for relationships. In the relationship declaration we + * can then just use a string value + * + * ``` + * // ... + * relation: Model.ManyToManyRelation, + modelClass: 'charge_version.model', + // ... + ``` + + We don't want to do this in every model so set it in the `BaseModel` as Objection recommends. + */ + static get modelPaths () { + return [__dirname] + } +} + +module.exports = BaseModel diff --git a/app/models/charge_version.model.js b/app/models/charge_version.model.js new file mode 100644 index 0000000000..cd63803bbe --- /dev/null +++ b/app/models/charge_version.model.js @@ -0,0 +1,30 @@ +'use strict' + +/** + * @module ChargeVersionModel + */ + +const { Model } = require('objection') + +const BaseModel = require('./base.model.js') + +class ChargeVersionModel extends BaseModel { + static get tableName () { + return 'water.chargeVersions' + } + + static get relationMappings () { + return { + licences: { + relation: Model.BelongsToOneRelation, + modelClass: 'licence.model', + join: { + from: 'water.charge_versions.licence_id', + to: 'water.licences.licence_id' + } + } + } + } +} + +module.exports = ChargeVersionModel diff --git a/app/models/licence.model.js b/app/models/licence.model.js new file mode 100644 index 0000000000..079f71eadf --- /dev/null +++ b/app/models/licence.model.js @@ -0,0 +1,38 @@ +'use strict' + +/** + * @module LicenceModel + */ + +const { Model } = require('objection') + +const BaseModel = require('./base.model.js') + +class LicenceModel extends BaseModel { + static get tableName () { + return 'water.licences' + } + + static get relationMappings () { + return { + chargeVersions: { + relation: Model.HasManyRelation, + modelClass: 'charge_version.model', + join: { + from: 'water.licences.licence_id', + to: 'water.charge_versions.licence_id' + } + }, + regions: { + relation: Model.BelongsToOneRelation, + modelClass: 'region.model', + join: { + from: 'water.licences.region_id', + to: 'water.regions.region_id' + } + } + } + } +} + +module.exports = LicenceModel diff --git a/app/models/region.model.js b/app/models/region.model.js new file mode 100644 index 0000000000..6c23676639 --- /dev/null +++ b/app/models/region.model.js @@ -0,0 +1,30 @@ +'use strict' + +/** + * @module RegionModel + */ + +const { Model } = require('objection') + +const BaseModel = require('./base.model.js') + +class RegionModel extends BaseModel { + static get tableName () { + return 'water.regions' + } + + static get relationMappings () { + return { + licences: { + relation: Model.BelongsToOneRelation, + modelClass: 'licence.model', + join: { + from: 'water.regions.region_id', + to: 'water.licences.region_id' + } + } + } + } +} + +module.exports = RegionModel diff --git a/test/models/charge_version.model.test.js b/test/models/charge_version.model.test.js new file mode 100644 index 0000000000..d94fbd5a2e --- /dev/null +++ b/test/models/charge_version.model.test.js @@ -0,0 +1,19 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it } = exports.lab = Lab.script() +const { expect } = Code + +// Thing under test +const ChargeVersion = require('../../app/models/charge_version.model') + +describe('ChargeVersion model', () => { + it('returns data', async () => { + const query = await ChargeVersion.query() + + expect(query).to.exist() + }) +}) diff --git a/test/models/licence.model.test.js b/test/models/licence.model.test.js new file mode 100644 index 0000000000..3e03ccb96a --- /dev/null +++ b/test/models/licence.model.test.js @@ -0,0 +1,19 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it } = exports.lab = Lab.script() +const { expect } = Code + +// Thing under test +const Licence = require('../../app/models/licence.model.js') + +describe('Licence model', () => { + it('returns data', async () => { + const query = await Licence.query() + + expect(query).to.exist() + }) +}) diff --git a/test/models/region.model.test.js b/test/models/region.model.test.js new file mode 100644 index 0000000000..204399c5a1 --- /dev/null +++ b/test/models/region.model.test.js @@ -0,0 +1,19 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it } = exports.lab = Lab.script() +const { expect } = Code + +// Thing under test +const Region = require('../../app/models/region.model') + +describe('Region model', () => { + it('returns data', async () => { + const query = await Region.query() + + expect(query).to.exist() + }) +})