Kousha
Kousha

Reputation: 36189

Resolving Circular Dependency in NodeJS model

I have two models (using BookshelfJS, or BackboneJS, doesn't matter): modelA, modelB. modelA requires modelB and modelB requires modelA.

Initially, I had:

// modelA
var Bookshelf = require('bookshelf);
var modelB = require('./modelB');
var modelA = Bookshelf.Model.extend({});

module.exports = modelA;

// modelB
var Bookshelf = require('bookshelf);
var modelA = require('./modelA);
var modelB = Bookshelf.Model.extend({});

module.exports = modelB;

Then I read here about the Bookshelf.plugin('register'). So I changed my code to:

// modelA
var Bookshelf = require('bookshelf);
var modelB = Bookshelf.model('modelB');
var modelA = Bookshelf.Model.extend({});

Bookshelf.model('modelA', modelA);

// modelB
var Bookshelf = require('bookshelf);
var modelA = Bookshelf.model('modelA');
var modelB = Bookshelf.Model.extend({});

Bookshelf.model('modelB', modelB);

In case 1, there was a circular dependency, which was fixed in case 2. But now in case 2, when modelA is being bootstrapped, modelB is not defined yet, so Bookshelf.model('modelB') doesn't exist.

What do I do?

Upvotes: 2

Views: 3687

Answers (2)

jemiloii
jemiloii

Reputation: 25719

So @Kousha helped me out about being able to require inside Bookshelf.Model.extend I make a file for each of my model/model groups and then export the model. So I did this variation.

modelA.js

var modelA = Bookshelf.Model.extend({
    tableName : 'modelA',

    modelB() {
        this.belongsToMany(require('./modelB).modelB);
    }
});

module.exports = { modelA };

modelB.js

var modelB = Bookshelf.Model.extend({
    tableName : 'modelB',

    modelA() {
        this.belongsToMany(require('./modelA).modelA);
    }
});

module.exports = { modelB };

Upvotes: 0

Kousha
Kousha

Reputation: 36189

Okay, so the fix was quite easy. Here it is for anyone who is interested. require the model inside the .extend({})'s function that will use it. For instance:

// modelA (which requires modelB somewhere inside)
var Bookshelf = require('bookshelf);
var modelA = Bookshelf.Model.extend({
    tableName : 'modelA',

    someFunc : function() {
        var modelB = Bookshelf.model('modelB'); 
        // Now use modelB here
    }
});

Problem is that modelB is not bootstrapped when modelA is being bootstrapped. Requiring the modelB at the top of the page is then impossible. Instead, you require it inside the function. By then, your app is running and everything is bootstrapped.

Upvotes: 7

Related Questions