SequelizeJS HasOne关联错误

时间:2017-05-20 23:23:31

标签: javascript node.js postgresql orm sequelize.js

我对NodeJS和SequelizeJS相对较新,我正面临hasOne问题我正在构建的问题,我想知道您对此问题的看法,以找出我出错的地方和正确的方法来实现这个查询。

Association Here

使用sequelize-auto(pg-hstore)生成的模型。

Bloco模型:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('bloco_condominio', {
    id_bloco: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true
    },
    id_condominio: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: 'condominio',
        key: 'id_condominio'
      }
    },
    nm_bloco: {
      type: DataTypes.STRING,
      allowNull: true
    },
    ic_status: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: "A"
    }
  }, {
    tableName: 'bloco_condominio'
  });
};

公寓型号:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('apartamento', {
    id_apartamento: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true
    },
    id_condominio: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: 'condominio',
        key: 'id_condominio'
      }
    },
    nu_apto: {
      type: DataTypes.STRING,
      allowNull: true
    },
    id_bloco: {
      type: DataTypes.INTEGER,
      allowNull: true,
      references: {
        model: 'bloco_condominio',
        key: 'id_bloco'
      }
    },
    ic_status: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: "A"
    },
    dt_incl: {
      type: DataTypes.TIME,
      allowNull: false,
      defaultValue: sequelize.fn('now')
    },
    dt_ult_alt: {
      type: DataTypes.TIME,
      allowNull: false,
      defaultValue: sequelize.fn('now')
    }
  }, {
    tableName: 'apartamento'
  });
};

公寓服务:

"use strict";
var model = require('../models');
var Utils = require('../utils/utils');

var service = {};
var Apartamento = model.apartamento;
var Bloco = model.bloco_condominio;
var Morador = model.morador;
var Pessoa = model.pessoa;

//Incluir relação OneToMany
Apartamento.hasMany(Morador, { as: "Moradores", foreignKey: 'id_apartamento' });
Morador.belongsTo(Apartamento, { foreignKey: 'id_apartamento' });

Morador.hasMany(Pessoa, { as: "Pessoa", foreignKey: 'id_pessoa' });
Pessoa.belongsTo(Morador, { foreignKey: 'id_pessoa' });

Bloco.hasMany(Apartamento, { as: "Bloco", foreignKey: 'id_bloco' });
Apartamento.hasMany(Bloco, { foreignKey: 'id_bloco' }); 

service.getApartamentoById = function(idApartamento) {
    return Apartamento.findById(idApartamento, {
            include: [
                { model: Morador, as: 'Moradores', include: [
                    { model: Pessoa, as: 'Pessoa'}
                ]},
                { model: Bloco, as: 'Bloco' }
            ]
        })
        .then(function(data) {
            return data;
        })
        .catch(function(err) {
            throw 'Erro ao consultar apartamento por ID: ' + err.message + ' - Request: '+JSON.stringify(idApartamento);
        });
};

我可以完美地检索其他hasMany关联,但仍然没有找到一种方法以相反的方式这样做。

你们是否知道如何以正确的方式处理这个问题?

提前感谢您的帮助!

祝你好运, 恩里科贝加莫

1 个答案:

答案 0 :(得分:0)

为了让我更简单(只懂英语),我从Google翻译中抓住了以下内容:

Pessoa: Person
Morador: Dweller
Bloco: Block
Apartmento: Apartment

所以,Dweller可以有很多人,一个公寓可以有很多居民,一个街区可以有很多公寓。

您对其他型号的定义表明它们都是1:m,所以我遵循公寓和街区的假设。

考虑到这一点,以下内容应该有效。

Bloco.hasMany(Apartamento, { as: "Apartmento", foreignKey: 'id_bloco' });
Apartamento.belongsTo(Bloco, { foreignKey: 'id_bloco' }); 
  

注意:我已将as: "Bloco"更改为as: "Apartmento",将第二个hasMany更改为belongsTo。这可能是您的问题来自的地方。

修改:访问属于某个区块的公寓的方法是:

bloco.getApartmento(options)

我有这个承诺链:

Bloco.create()
.then(block => {
  return Promise.all([
    block,
    Apartamento.bulkCreate([{
      id_bloco: block.id_bloco
    }, {
      id_bloco: block.id_bloco
    }, {
      id_bloco: block.id_bloco
    }, {
      id_bloco: block.id_bloco
    }, {}])
  ])
})
.spread((bloco, apartment) => {
  return bloco.getApartamento()
})
.then(apartments => {
  console.log(apartments.length); --> Logs 4 which matches the bulk create.
})

如果我被误解了,并且它应该是一个n:m关系(公寓/街区),那么你应该在每个模型上使用belongsToMany并识别through选项。

Bloco.belongsToMany(Apartamento, { 
    as: "Apartmentos", 
    foreignKey: 'id_bloco', 
    through: "BlocoAparmento" 
});
Apartamento.belongsToMany(Bloco, { 
    as: "Blocos", 
    foreignKey: 'id_apartmento', 
    through: "BlocoAparmento" 
}); 

这将创建一个名为" BlockApartmento"的n:m连接表。如果您定义该模型,并使用模型而不是字符串,则您可以完全控制模型设置。

这将为您提供Bloco.getApartmentos(方法以及相反方向(Apartmento.getBlocos()以及setAssociationaddAssoc...

http://docs.sequelizejs.com/manual/tutorial/associations.html#belongs-to-many-associations