【问题标题】:Node.js Sequelize virtual column pulling value from other modelNode.js Sequelize 虚拟列从其他模型中提取值
【发布时间】:2019-10-02 14:13:08
【问题描述】:

我正在使用 Sequelize 5.7,尝试使用虚拟数据类型,
将相关信息提取到模型中。

给定简化的companyuser 模型,我如何获得company.name
进入user.companyname ?

公司

  let Schema = sequelize.define(
    "company",
    {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
      },
      name: {
        type: DataTypes.STRING(45)
      }
    }
  );

用户

  let Schema = sequelize.define(
    "user",
    {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
      },
      login: {
        type: DataTypes.STRING(45),
        unique: true
      },
      company: {
          type: DataTypes.INTEGER.UNSIGNED,
          references: {
            model: sequelize.model('company'),
            key: 'id'
          }
      },

      /* This companyname contruct is pure fantasy, and the target of my question */

      companyname: {
        type: new DataTypes.VIRTUAL(DataTypes.STRING,['company']),
          references: {
            model: 'company',
            key: 'name'
          }
      }
    }
  );

【问题讨论】:

    标签: mysql node.js orm sequelize.js


    【解决方案1】:

    在你的情况下,我认为使用关系(关联)是一个更好的主意

    Sequelize Associations

    const User = sequelize.define('user', {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
      },
      login: {
        type: DataTypes.STRING(45),
        unique: true
      },
      company_id: {
        type: DataTypes.INTEGER.UNSIGNED,
      },
    });
    
    const Company = sequelize.define('company', {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true,
      },
      name: {
        type: DataTypes.STRING,
      },
    });
    
    User.belongsTo(Company, {
      foreignKey: 'company_id', // you can use this to customize the fk, default would be like companyId
    });
    
    Company.hasMany(User);
    

    然后在调用你的模型时,你会执行以下操作:

    User.findAll({ include: Company }).then(users => console.log(users));
    

    【讨论】:

    • 是的。这几乎就是我在 3 个月前所做的事情 :) 我仍然希望有一些偷偷摸摸的解决方案,但我错过了,因为这不是最佳的。
    【解决方案2】:

    我通过在模型中使用type: DataTypes.VIRTUAL 解决了这个问题

    const { Model, DataTypes } = require('sequelize');
    
    class User extends Model {
        static init(sequelize) {
            super.init({
                id: {
                    type: DataTypes.INTEGER.UNSIGNED,
                    autoIncrement: true,
                    primaryKey: true
                },
                login: {
                    type: DataTypes.STRING(45),
                    unique: true
                },
                company_id: {
                    type: DataTypes.INTEGER.UNSIGNED,
                },
                companyname:{
                    type: DataTypes.VIRTUAL,
                    get() {
                        return this.Company?.get().name;
                    },
                    set(/*value*/) {
                        throw new Error('Do not try to set the `companyname` value!');
                    }
                },
            }, {
                sequelize
            })
        }
        static associate(models) {
            this.belongsTo(Company, {
              foreignKey: 'company_id',
            });
        }
    }
    
    module.exports = User;
    

    搜索只包括关联:

    User.findAll({ include: Company })
    

    我通常在不同的文件中使用“类”创建每个模型,但如果您需要,只需在@jalex19 解决方案中包含以下代码

    companyname:{
        type: DataTypes.VIRTUAL,
        get() {
            return this.Company?.get().name;
        },
        set(/*value*/) {
            throw new Error('Do not try to set the `fullName` value!');
        }
    },
    

    【讨论】:

    • :) 谢谢。如果我能记住需要它的项目,我会尝试你的解决方案,而且我仍然有源代码。不过看起来确实很有希望。
    猜你喜欢
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2015-06-01
    • 1970-01-01
    相关资源
    最近更新 更多