首页 > 解决方案 > 如何将两个模型与续集关联?(1:n) 和 (m:n)

问题描述

我想做3张桌子ClienteObraEngenheiro

关联:ClienteObra(1:n) 相关并EngenheiroObra(m:n) 相关。

客户端.js:

const db = require('./db');
const Obra = require('./Obra');

const Cliente = db.sequelize.define('clientes', {
    nome: {
        type: db.Sequelize.STRING
    },
    celular: {
        type: db.Sequelize.STRING
    },
    cpf: {
        type: db.Sequelize.STRING
    }
});

Cliente.hasMany(Obra);

//Cliente.sync({force: true})

module.exports = Cliente

Engenheiro.js:

const db = require('./db');
const Registro = require('./Registro');

const Engenheiro = db.sequelize.define('engenheiros', {
    nome: {
        type: db.Sequelize.STRING
    }
    crea: {
        type: db.Sequelize.STRING
    },
    salario: {
        type: db.Sequelize.FLOAT
    }
});

Engenheiro.hasMany(Obra);

//Engenheiro.sync({force: true})

module.exports = Engenheiro

Obra.js:

const db = require('./db')
const Cliente = require('./Cliente');
const Registro = require('./Registro');

const Obra = db.sequelize.define('obras', {
    bairro: {
        type: db.Sequelize.STRING
    },
    cidade: {
        type: db.Sequelize.STRING
    },
    estado: {
        type: db.Sequelize.STRING
    }
});

Obra.belongsTo(Cliente);
Obra.hasMany(Engenheiro);

//Obra.sync({force: true})

module.exports = Obra

当我调用“node something.js”时出现错误消息:
“something.hasMany 调用的东西不是 Sequelize.Model 的子类”

更新:
我尝试了 Anatoly 所说的,它执行时没有任何错误,但我没有看到新的出现列并且控制台上没有出现关联的sql代码,我做错了吗?
我创建了一个新模型“Registro.js”并将“.sync()”和关联移动到一个新文件:

Association.js

const Cliente = require('./Cliente');
const Engenheiro = require('./Engenheiro');
const Obra = require('./Obra');
const Registro = require('./Registro');

Cliente.sync({force: true});
Engenheiro.sync({force: true});
Obra.sync({force: true});
Registro.sync({force: true});

Cliente.hasMany(Obra);
Obra.belongsTo(Cliente);
Obra.belongsToMany(Engenheiro, { through: Registro });
Engenheiro.belongsToMany(Obra, { through: Registro });

Registro.js(所有模型都遵循相同的结构):

const db = require('./db');

const Registro = db.sequelize.define('registros', {});

module.exports = Registro

控制台(表格看起来更大,因为我添加了新列):

Executing (default): DROP TABLE IF EXISTS `clientes`;
Executing (default): DROP TABLE IF EXISTS `engenheiros`;
Executing (default): DROP TABLE IF EXISTS `obras`;
Executing (default): DROP TABLE IF EXISTS `registros`;
Executing (default): CREATE TABLE IF NOT EXISTS `clientes` (`id` INTEGER NOT NULL auto_increment , `nome` VARCHAR(255), `end` VARCHAR(255), `fone` VARCHAR(255), `celular` VARCHAR(255), `cpf` VARCHAR(255), `cnpj` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `obras` (`id` INTEGER NOT NULL auto_increment , `end` VARCHAR(255), `bairro` VARCHAR(255), `cidade` VARCHAR(255), `estado` VARCHAR(255), `metragem` VARCHAR(255), `quartos` VARCHAR(255), `wc` VARCHAR(255), `infraestrutura` TINYINT(1), `garagem` TINYINT(1), `andar` VARCHAR(255), `edificio` VARCHAR(255), `situacao` VARCHAR(255), `dataInicio` DATETIME, `dataTermino` DATETIME, `observacao` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `engenheiros` (`id` INTEGER NOT NULL auto_increment , `nome` VARCHAR(255), `end` VARCHAR(255), `fone` VARCHAR(255), `celular` VARCHAR(255), `cpf` VARCHAR(255), `crea` VARCHAR(255), `salario` FLOAT, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `registros` (`id` INTEGER NOT NULL auto_increment , `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `clientes`
Executing (default): SHOW INDEX FROM `obras`
Executing (default): SHOW INDEX FROM `engenheiros`
Executing (default): SHOW INDEX FROM `registros`

Update2:
我设法通过将关联放在之前.sync()并更改force为来创建关系列,alter但我仍然不明白关联是如何工作的。
在下面的示例中,当我更改.sync(alter: true)某些表的顺序时,既没有创建也没有更新,并且关联失败。

const Cliente = require('./Cliente');
const Obra = require('./Obra');
const Engenheiro = require('./Engenheiro');
const Registro = require('./Registro');

Cliente.hasMany(Obra);
Obra.belongsTo(Cliente);
Obra.belongsToMany(Engenheiro, {through: Registro});
Engenheiro.belongsToMany(Obra, {through: Registro});

Obra.sync({alter: true});
Engenheiro.sync({alter: true});
Cliente.sync({alter: true});
Registro.sync({alter: true});

为什么sync(force:true)导致代码失败以及为什么sync事情的顺序?

标签: mysqlnode.jssequelize.js

解决方案


首先,您需要做的是将所有关联定义移到模型文件之外,或者将它们添加到模型的associate方法中,以便在所有模型都已注册后稍后调用它们,例如,请参见我的答案

其次,如果您需要 M:N 关联,您应该创建一个附加表并定义一个模型(例如它的名称EngenheiroObra)以链接Engenheiro到模型的ObrausingbelongsToMany方法。

Engenheiro.belongsToMany(Obra, { though: EngenheiroObra });
Obra.belongsToMany(Engenheiro, { though: EngenheiroObra });

更新。如果您已经将模型文件移到外部,您还需要从模型文件中删除所有关联定义。而且你不需要旧的hasMany联想,因为你用旧的联想代替了它们belongsToMany


推荐阅读