如何使用Sequelize更新Hotel关联的HotelFilters表记录?
酒店筛选器关联记录的更新问题
我有三个数据表:Hotel、Filters、HotelFilters,目前已经通过以下代码实现了创建Hotel、Filters及关联HotelFilters记录的功能:
// Create and Save a new Hotel exports.create = async (req, res) => { // Create a Hotel const hotel = { "title": req.body.title, ... }; // 这是一个整数数组 - 假设当前是[1,2,3,4] const filters = req.body.filters; await Hotel.create(hotel) .then(createdHotel => { // 向HOTELFILTERS表添加记录************************* filters.forEach((filter) => { createdHotel.createHotelFilter({ "filterId": filter }); }); res.send(createdHotel); }) .catch(err => { res.status(500).send({ "message": err.message || "创建酒店时发生了一些错误。" }); }); };
这段代码运行正常,但现在遇到了更新场景的问题:当我提交如下移除了筛选器4的数据时,希望能自动删除HotelFilters表中对应的关联记录,请问该如何实现?
{ "title": "Hotel", "description": "This is a description", "hotelFilters": [1,2,3 ] }
解决方案
可以通过以下步骤实现关联记录的同步更新:
- 定位目标酒店:根据请求中的酒店ID找到要更新的
Hotel记录 - 对比筛选器集合:获取该酒店当前已关联的所有筛选器ID,和提交的新筛选器数组做对比,找出需要删除和新增的筛选器
- 执行删除与新增:删除不在新数组中的关联记录,新增新数组中未存在的关联记录
- 返回更新结果:返回更新后的酒店信息
具体代码实现如下(基于Sequelize框架,和你的创建逻辑保持一致):
// Update a Hotel and sync HotelFilters exports.update = async (req, res) => { const hotelId = req.params.id; // 假设请求URL中包含酒店ID const { title, description, hotelFilters: newFilters } = req.body; try { // 找到要更新的酒店 const hotel = await Hotel.findByPk(hotelId); if (!hotel) { return res.status(404).send({ message: "未找到指定酒店" }); } // 更新酒店基础信息 await hotel.update({ title, description }); // 获取当前已关联的筛选器ID列表 const existingFilters = await hotel.getHotelFilters(); const existingFilterIds = existingFilters.map(item => item.filterId); // 计算需要删除的筛选器(现有但不在新列表中) const filtersToDelete = existingFilterIds.filter(id => !newFilters.includes(id)); // 计算需要新增的筛选器(新列表中但不存在) const filtersToAdd = newFilters.filter(id => !existingFilterIds.includes(id)); // 删除多余的关联记录 if (filtersToDelete.length > 0) { await HotelFilters.destroy({ where: { hotelId: hotel.id, filterId: filtersToDelete } }); } // 新增缺失的关联记录 filtersToAdd.forEach(filterId => { hotel.createHotelFilter({ filterId }); }); // 返回更新后的酒店(可关联查询筛选器一起返回) const updatedHotel = await Hotel.findByPk(hotelId, { include: [{ model: Filters, through: { attributes: [] } }] }); res.send(updatedHotel); } catch (err) { res.status(500).send({ message: err.message || "更新酒店时发生错误" }); } };
关键说明
- 使用
getHotelFilters()获取酒店当前关联的所有筛选器记录,提取ID后和新数组对比 - 通过
HotelFilters.destroy()批量删除不需要的关联记录,避免循环删除提高效率 - 新增逻辑和创建时保持一致,只添加新出现的筛选器
- 最后返回酒店时可以通过
include关联查询筛选器,让返回结果更完整
内容的提问来源于stack exchange,提问作者avi
相关产品推荐
相关产品推荐

