【问题标题】:How to include model in belongstToMany relation in Sequelize如何在 Sequelize 中的 belongstToMany 关系中包含模型
【发布时间】:2021-04-28 13:20:24
【问题描述】:

我想在我的 sequelize 查询模型中添加,但我不知道如何正确执行此操作。

我有两张桌子:RegionsCountries。它们之间有一个名为belongsToMany 的关系,它通过表region_countries,我有外键region_idcountry_id。对于RegionCountries,我有带有翻译的表格,例如:表格translate_trgions 有区域和语言代码名称(en、fr、ru 等)。我正在获取regionscountries 的列表以及他们的翻译。

我的区域模型

class Region extends Model {}
Region.init(
  {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
  },
  { sequelize, timestamps: false, tableName: 'regions', modelName: 'Region' }
);

class RegionTranslate extends Model {}
RegionTranslate.init(
  {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: true,
    },
    region_id: {
      type: DataTypes.INTEGER.UNSIGNED,
      references: {
        model: Region,
        key: 'id',
      },
    },
    language_code: {
      type: DataTypes.INTEGER.UNSIGNED,
      references: {
        model: Language,
        key: 'code',
      },
    },
  },
  {
    sequelize,
    timestamps: false,
    tableName: 'regions_description',
    modelName: 'RegionTranslate',
  }
);

class RegionsCountries extends Model {}
RegionsCountries.init(
  {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    region_id: {
      type: DataTypes.INTEGER.UNSIGNED,
      references: {
        model: Region,
        key: 'id',
      },
    },
    country_id: {
      type: DataTypes.INTEGER.UNSIGNED,
      references: {
        model: Country,
        key: 'id',
      },
    },
  },
  {
    sequelize,
    timestamps: false,
    tableName: 'region_countries',
    modelName: 'RegionsCountries',
  }
);

Region.hasMany(RegionTranslate, {
  foreignKey: 'region_id',
  as: 'translate_regions',
});
RegionTranslate.belongsTo(Region, { foreignKey: 'region_id' });

Region.belongsToMany(Country, {
  through: RegionsCountries,
  foreignKey: 'region_id',
});
Country.belongsToMany(Region, {
  through: RegionsCountries,
  foreignKey: 'country_id',
});

Region.belongsToMany(CountryTranslate, {
  through: RegionsCountries,
  as: 'translate_countries',
  foreignKey: 'country_id',
  otherKey: 'id',
});

我的国家模式

class Country extends Model {}
Country.init(
  {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    code: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    unicode: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
  },
  { sequelize, timestamps: false, tableName: 'countries', modelName: 'Country' }
);

class CountryTranslate extends Model {}
CountryTranslate.init(
  {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    language_code: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: Language,
        key: 'code',
      },
    },
    country_id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: Country,
        key: 'id',
      },
    },
    name: {
      type: DataTypes.BOOLEAN,
      allowNull: true,
    },
    description: {
      type: DataTypes.BOOLEAN,
      allowNull: true,
    },
  },
  {
    sequelize,
    timestamps: false,
    tableName: 'countries_description',
    modelName: 'CountryTranslate',
  }
);

Country.hasMany(CountryTranslate, {
  foreignKey: 'country_id',
  as: 'translate_countries',
});
CountryTranslate.belongsTo(Country, { foreignKey: 'country_id' });

Country.belongsToMany(Region, {
  through: RegionsCountries,
  foreignKey: 'country_id',
});

我在 RegionController 中的查询

const regions = await Region.findAll({
  attributes: {
    include: [[Sequelize.literal('translate_regions.name'), 'name']],
  },
  include: [
    {
      model: Country,
      attributes: {
        include: [[Sequelize.literal('translate_countries.name'), 'name']],
      },
      through: {
        attributes: [],
      },
    },
    {
      model: RegionTranslate,
      as: 'translate_regions',
      where: { language_code: language },
      attributes: [],
    },
    {
      model: CountryTranslate,
      as: 'translate_countries',
    },
  ],
});

我得到的输出

"regions": [
  {
    "id": 4,
    "name": "Europe",
    "Countries": [
      {
        "id": 3,
        "code": "dza",
        "unicode": "12",
        "name": "Ангола"
      }
    ],
    "translate_countries": [
      {
        "id": 10,
        "language_code": "ru",
        "country_id": 5,
        "name": "Ангола",
        "description": null,
        "RegionsCountries": {
          "id": 10,
          "region_id": 4,
          "country_id": 4
        }
      }
    ]
  }
]

我想要的输出

"regions": [
  {
    "id": 4,
    "name": "Europe",
    "Countries": [
      {
        "id": 4,
        "code": "and",
        "unicode": "20",
        "name": "Andorra"
      }
    ]
  }
]

【问题讨论】:

    标签: mysql node.js express sequelize.js


    【解决方案1】:

    在通过关系表为多对多设置模型关联时,您需要指定关系表中作为源表主键外键的列,以及作为源表主键的列。相关表主键的“其他”外键。指定 as 属性也有助于识别关系。

    这是一个示例,请检查其他关系。

    // use otherKey to indicate the relationship
    // country.id -> country_id, region_id -> region.id
    Country.belongsToMany(Region, {
      as: 'regions',
      through: RegionsCountries,
      foreignKey: 'country_id',
      otherKey: 'region_id'
    });
    

    当您查询相关记录时,我们不能在查询中指定throughas 属性。

    Country.findByPk(countryId, {
      include: [{
        model: Region,
        through: RegionsCountries,
        as: 'regions',
      }],
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 1970-01-01
      相关资源
      最近更新 更多