简体   繁体   中英

sequelizejs many-to-many relationship

I am trying to setup a two-way, many-to-many relationship between two models, User and School. There is a join table, 'user_school' that looks like:

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | mediumint(9) | NO   | PRI | NULL    | auto_increment |
| user_id    | mediumint(9) | NO   | MUL | NULL    |                |
| school_id  | mediumint(9) | NO   |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
| updatedat  | datetime     | YES  |     | NULL    |                |
| createdat  | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

(I created the various createdAt and updatedAt fields to try to get the model working properly. That's not the problem now. But I'm still not sure the proper way to define those fields, camel or snake case.)

Here is how I defined the relationships:

School.belongsToMany(User, { through: 'user_school', foreignKey: 'school_id'});
User.belongsToMany(School, { through: 'user_school', foreignKey: 'user_id'});

The second relationship works. I can call, user.getSchools(), and get the schools associated with the user. But the first relationship doesn't work. when I call, school.getUsers(), I get an error like this:

Executing (default): SELECT `id`, `email`, `name`, `description`, `address1`, `address2`, `city`, `state`, `zip`, `url`, `phone`, `deleted`, `approved`, `added_by` AS `addedBy`, `sub_count` AS `subCount`, `created_at` AS `createdAt`, `updated_at` AS `updatedAt` FROM `school` AS `school` WHERE `school`.`id` = '0';

Unhandled rejection TypeError: Cannot read property 'replace' of undefined
    at Object.module.exports.removeTicks (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/utils.js:345:13)
    at Object.module.exports.addTicks (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/utils.js:341:29)
    at Object.QueryGenerator.quoteIdentifier (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/dialects/mysql/query-generator.js:300:18)
    at Object.QueryGenerator.joinIncludeQuery (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1647:66)
    at generateJoinQueries (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1373:38)
    at Object.<anonymous> (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1411:27)
    at Array.forEach (native)
    at Object.QueryGenerator.selectQuery (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1410:10)
    at QueryInterface.select (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/query-interface.js:657:25)
    at null.<anonymous> (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/lib/model.js:1377:32)
    at bound (domain.js:280:14)
    at runBound (domain.js:293:12)
    at tryCatcher (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/node_modules/bluebird/js/release/util.js:11:23)
    at Promise._settlePromiseFromHandler (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:489:31)
    at Promise._settlePromise (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:546:18)
    at Promise._settlePromise0 (/Users/andrunix/code/learning/hapi-sequelize/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:591:10)

If I run the SQL shown above, the query works correctly. So that part of the logic seems to be working.

If I reverse the order the relationships are defined, like so:

User.belongsToMany(School, { through: 'user_school', foreignKey: 'user_id'});
School.belongsToMany(User, { through: 'user_school', foreignKey: 'school_id'});

this causes the "breakage" to happen on the other relationship. The school.getUsers() call works and the user.getSchools() call fails.

Turns out, for whatever reason, I needed to add, 'otherKey' to my relationship. Here's what worked:

User.belongsToMany(School, { through: 'user_school', foreignKey: 'user_id', otherKey: 'school_id'});
School.belongsToMany(User, { through: 'user_school', foreignKey: 'school_id', otherKey: 'user_id'});

Thanks to Mick Hansen on #sequelizejs on freenode for the assistance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM