【问题标题】:Associations using Sequelize: Many to Many relationships使用 Sequelize 的关联:多对多关系
【发布时间】:2021-11-05 07:56:20
【问题描述】:

我正在尝试构建一个使用 express、sequelize 和 mysql 的网络聊天应用程序。我的逻辑是一个用户属于许多聊天,一个聊天属于许多用户。我为这个关联创建了一个名为User_chat 的联结表。我最近才了解续集,并且仍在掌握逻辑。我有一个简单的获取请求:

router.get('/', withAuth, async (req, res) => {
  try {
    const userChatRooms = await Chat.findAll({
      include: [{ model: User_chat }]
    });

    console.log(userChatRooms);
    res.json(userChatRooms);
  } catch (e) {
    console.log(e);
    res.status(500).json(e);
  }

});

它总是返回以下错误:

EagerLoadingError [SequelizeEagerLoadingError]: User_chat is not associated to Chat!
    at Function._getIncludedAssociation (/Users/nem/Desktop/proj/chat/node_modules/sequelize/lib/model.js:710:13)
    at Function._validateIncludedElement (/Users/nem/Desktop/proj/chat/node_modules/sequelize/lib/model.js:614:53)
    at /Users/nem/Desktop/proj/chat/node_modules/sequelize/lib/model.js:509:37
    at Array.map (<anonymous>)
    at Function._validateIncludedElements (/Users/nem/Desktop/proj/chat/node_modules/sequelize/lib/model.js:504:39)
    at Function.findAll (/Users/nem/Desktop/proj/chat/node_modules/sequelize/lib/model.js:1723:12)
    at async /Users/nem/Desktop/proj/chat/controllers/api/chat-routes.js:8:27

我希望能够返回登录用户的chat_name。我想到的查询是:

select c.email, a.chat_name from chat a
left join user_chat b on a.chat_id = b.chat_id
left join user c on b.user_id = c.user_id
where c.user_id = 1;

我的关联表如下图:

const { Chat } = require('./Chat');
const { User } = require('./User');
const { User_chat } = require('./User_chat');
const { Message } = require('./Message');

// Defining associations between the models

//TODO: Define between user and chat - many to many
//Junction table is user_chat
Chat.belongsToMany(User, { through: 'User_chat' });

//TODO: Define between chat and user - many to many
//Junction table is user_chat
User.belongsToMany(Chat, { through: 'User_chat' });

//TODO: Define between user and message - one to many
User.hasMany(Message, {
  foreignKey: 'sender_id',
  onDelete: 'CASCADE'
});

//TODO: Define between chat and message - one to many
Chat.hasMany(Message, {
  foreignKey: 'chat_id',
  onDelete: 'CASCADE'
});

//TODO: Define between message and chat - one to one
Message.belongsTo(Chat, {
  foreignKey: 'chat_id'
});

//TODO: Define between message and user - one to one
Message.belongsTo(User, {
  foreignKey: 'sender_id'
});

module.exports = {
  Chat,
  User,
  User_chat,
  Message
};

模型设计


const { Model, DataTypes } = require('sequelize');
const bcrypt = require('bcryptjs');
const sequelize = require('../config/connection.js');

class User extends Model {
  checkPassword(userLoginPassword) {
    return bcrypt.compareSync(userLoginPassword, this.password);
  }
}

User.init(
  //TODO: Define the model for users
  {
    user_id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    username: {
      type: DataTypes.STRING(30),
      allowNull: false,
      unique: true
    },
    email: {
      type: DataTypes.STRING(255),
      allowNull: false,
      unique: true
    },
    password: {
      type: DataTypes.STRING(255),
      allowNull: false
    }
  },
  {
    hooks: {
      async beforeCreate(newUserData) {
        newUserData.password = await bcrypt.hash(newUserData.password, 10);
        return newUserData;
      }
      // async beforeUpdate(updatedUserData) {
      //   updatedUserData.password = await bcrypt.hash(
      //     updatedUserData.password,
      //     10
      //   );
      //   return updatedUserData;
      // }
    },
    sequelize,
    timestamps: false,
    freezeTableName: true,
    underscored: true
  }
);

module.exports = { User };
const { Model, DataTypes } = require('sequelize');

const sequelize = require('../config/connection.js');

class Chat extends Model {}

Chat.init(
  //TODO: Define the model for chats
  {
    chat_id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    chat_name: {
      type: DataTypes.STRING(255),
      unique: true,
      allowNull: false
    }
  },
  {
    sequelize,
    timestamps: false,
    freezeTableName: true,
    underscored: true
  }
);

module.exports = { Chat };
const { Model, DataTypes } = require('sequelize');

const sequelize = require('../config/connection.js');

class User_chat extends Model {}

User_chat.init(
  //Junction table for the user and chat id since it will be many to many.
  {
    user_id: {
      type: DataTypes.INTEGER
      references: {
        model: 'User',
        key: 'user_id'
      }
    },
    chat_id: {
      type: DataTypes.INTEGER
      references: {
      model: 'Chat',
      key: 'chat_id'
      }
    },
    is_owner: {
      type: DataTypes.BOOLEAN
    }
  },
  {
    sequelize,
    timestamps: false,
    freezeTableName: true,
    underscored: true
  }
);

module.exports = { User_chat };
const { Model, DataTypes, literal } = require('sequelize');

const sequelize = require('../config/connection.js');

class Message extends Model {}

Message.init(
  //TODO: Define the model for message
  {
    message_id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    message_content: {
      type: DataTypes.STRING(255),
      allowNull: false
    },
    chat_id: {
      type: DataTypes.INTEGER,
      references: {
        model: 'chat',
        key: 'chat_id'
      }
    },
    sender_id: {
      type: DataTypes.INTEGER,
      references: {
        model: 'user',
        key: 'user_id'
      }
    }
    // created_at: {
    //   type: 'TIMESTAMP',
    //   defaultValue: literal('CURRENT_TIMESTAMP'),
    //   allowNull: false
    // }
  },
  {
    sequelize,
    timestamps: false,
    freezeTableName: true,
    underscored: true
  }
);

module.exports = { Message };

【问题讨论】:

    标签: javascript mysql node.js express sequelize.js


    【解决方案1】:

    如果您希望获取所有用户的聊天记录,请在 include 中指定 User 模型,而不是连接模型。此外,向用户发起查询更容易,因为您希望为其添加条件:

    const userWithChats = await User.findAll({
          where: {
            user_id: 1
          },
          attributes: ['email'],
          include: [{
            model: Chat,
            attributes: ['chat_name']
          }]
        });
    const chats = userWithChats.Chats
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 2014-04-15
      • 1970-01-01
      相关资源
      最近更新 更多