hasMany not working with valid models
See original GitHub issueI have two valid models, Customer and Order, defined in two separate modules.
Example code (omitted columns / options):
var Customer = require('./order');
var Order = sequelize.define('order', attrs, opts);
Order.belongsTo(Customer, {foreignKey: 'local_customer_id', targetKey: 'id'});
module.exports = Order;
Imagine that Customer is the same, short of the Order.belongsTo(Customer, {foreignKey: 'local_customer_id', targetKey: 'id'});
being replaced with Customer.hasMany(Order, {foreignKey: 'id', targetKey: 'local_customer_id'});
, and a require for var Order
at the top instead of Customer
.
The problem here is, when running the Customer.hasMany
line, I get the error ‘hasMany called with something that’s not an instance of Sequelize.Model’. However, if I put both of the lines into the Order module, such as this:
Order.belongsTo(Customer, {foreignKey: 'local_customer_id', targetKey: 'id'});
Customer.hasMany(Order, {foreignKey: 'id', targetKey: 'local_customer_id'});
That works fine, and the relations work.
My question is, why is this happening? The sequelize models work exactly as is, so my definition of them is correct. And they’re both exported via a module.exports = Order
-esque line, so they’re both exported correctly.
Issue Analytics
- State:
- Created 8 years ago
- Comments:5 (3 by maintainers)
This has nothing to do with sequelize. You can read more about circular dependencies here. In other words, you must first define both Models, export them and THEN require one another and call these associative functions on them to avoid unmet dependencies, something like this:
Order:
Customer:
yeah it is 😁, you can just do
module.exports = Order;
no difference.Actually it’s not asynchronous at all, it’s just that when you require a module node will try to load it, now if you have something like this:
You would expect that
foo
should be 1! but it’s not!let’s reason about what is happening.
require('./b')
bar
yet! node has not yet “seen” theexports.bar = 1;
linerequire('./a')
'./a'
! so it simply returns that not-fully-initialized-cached-version of'./a'
.bar
'./a'
doesn’t have.bar
yet! so it assignsundefined
to foo!'./b'
finishes!'./a'
to continue execution..foo
.foo
was set toundefined
in 8! so it also assignsundefined
to.bar
.bar
which is too late (same reason for the error you saw)'./a'
ends'./main'
'./main'
endsonly if in
a.js
we did this instead:We would all go home happy 😄
This is the reason why you see that error. you should understand how imperative programming languages work, and since js is single threaded it’s absolutely imperative.