0

I have an external library (Objection.js) that I'm using in my Node.js app. I created a base model class that extends Objection's Model class for my entity models:

const { Model } = require('objection')

class ModelBase extends Model {
    // implementation not important for this question
}

In my model classes that extend my base, there are times, specifically when coding the relationMappings, where I have to access properties/enumerations on the Model base class. I could do this in my extended models like this:

const ModelBase = require('./model-base')

class SomeModel extends ModelBase {
    static get relationMappings () {
        const SomeOtherModel = require('./some-other-model')
        return {
            someOtherModel: {
                relation: ModelBase.BelongsToOneRelation,
                modelClass: SomeOtherModel,
                // etc.
            }
        }
    }
}

Notice the relation: ModelBase.BelongsToOneRelation line. This works, but I think it is misleading, as BelongsToOneRelation is NOT a member of ModelBase. What seems more explicit and correct to me is to import/require the Model from Objection so I can access the BelongsToOneRelation from there, like:

const { Model } = require('objection')
// other code just like above until the relationMappings...
                relation: Model.BelongsToOneRelation

I prefer this approach. Will it cause problems, like require loops or the JavaScript version of a circular dependency, if I import/require a class that is already in scope in the inheritance chain?

AJ.
  • 16,368
  • 20
  • 95
  • 150
  • 4
    No, it won’t cause problems. “Already in scope in the inheritance chain” isn’t a thing, scopes and inheritance are completely separate. – Ry- Apr 12 '19 at 16:43
  • OK, thanks, should I delete my question then since you answered it? – AJ. Apr 12 '19 at 16:44
  • 2
    Rule of thumb: if you think someone else will have the same question, you can leave it up, otherwise it’s safe to delete. – Ry- Apr 12 '19 at 16:45

2 Answers2

2

Will it cause problems, like require loops or the JavaScript version of a circular dependency, if I import/require a class that is already in scope in the inheritance chain?

No. A module will be executed when required for the first time, then if the execution finished the exports object gets cached, and further require()s will return the same object.

If you have a circular dependency, one of the require()s will return the exports object before the module executed, so the exports object will be empty by then, but will be filled up with properties later on.

Therefore even circular dependencies might work correctly, but if they fail it will cause you headaches so always try to not cause that.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
2

I think it is misleading, as .BelongsToOneRelation is NOT a member of ModelBase

Actually it is: it is an inherited member.

I prefer to explicitly import the superclass and access the member there. Will it cause problems, like require loops or the JavaScript version of a circular dependency?

No, it won't. The inheritance hierarchy and scope have nothing to do with your module dependencies.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375