调用了Sequelize Assosication而不是Sequelize.Model的子类的东西 [英] Sequelize Assosication called with something that's not a subclass of Sequelize.Model

查看:533
本文介绍了调用了Sequelize Assosication而不是Sequelize.Model的子类的东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在模型中添加Sequelize的关联时,我遇到了错误"...用非Sequelize.Model的子类调用的错误",它称为错误,即所谓的错误不是Sequelize Model.

I'm having error "...called with something that's not a subclass of Sequelize.Model" when I add association of Sequelize in my model it called error that what I call is not Sequelize Model

E:...\Projects\WebApps\hr1\hr1\node_modules\sequelize\lib\associations\mixin.js:81
      throw new Error(this.name + '.' + Utils.lowercaseFirst(Type.toString()) + ' called with something that\'s not a subclass of Sequelize.Model');
      ^

Error: user_employee_tm.class BelongsTo extends Association {
  constructor(source, target, options) {
    super(source, target, options);

    this.associationType = 'BelongsTo';
    this.isSingleAssociation = true;
    this.foreignKeyAttribute = {};

    if (this.as) {
      this.isAliased = true;
      this.options.name = {
        singular: this.as
      };
    } else {
      this.as = this.target.options.name.singular;
      this.options.name = this.target.options.name;
    }

    if (_.isObject(this.options.foreignKey)) {
      this.foreignKeyAttribute = this.options.foreignKey;
      this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
    } else if (this.options.foreignKey) {
      this.foreignKey = this.options.foreignKey;
    }

    if (!this.foreignKey) {
      this.foreignKey = Utils.camelizeIf(
        [
          Utils.underscoredIf(this.as, this.source.options.underscored),
          this.target.primaryKeyAttribute
        ].join('_'),
        !this.source.options.underscored
      );
    }

    this.identifier = this.foreignKey;

    if (this.source.rawAttributes[this.identifier]) {
      this.identifierField = this.source.rawAttributes[this.identifier].field || this.identifier;
    }

    this.targetKey = this.options.targetKey || this.target.primaryKeyAttribute;
    this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
    this.targetKeyIsPrimary = this.targetKey === this.target.primaryKeyAttribute;

    this.targetIdentifier = this.targetKey;
    this.associationAccessor = this.as;
    this.options.useHooks = options.useHooks;

    // Get singular name, trying to uppercase the first letter, unless the model forbids it
    const singular = Utils.uppercaseFirst(this.options.name.singular);

    this.accessors = {
      get: 'get' + singular,
      set: 'set' + singular,
      create: 'create' + singular
    };
  }

  // the id is in the source table
  injectAttributes() {
    const newAttributes = {};

    newAttributes[this.foreignKey] = _.defaults({}, this.foreignKeyAttribute, {
      type: this.options.keyType || this.target.rawAttributes[this.targetKey].type,
      allowNull: true
    });

    if (this.options.constraints !== false) {
      const source = this.source.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
      this.options.onDelete = this.options.onDelete || (source.allowNull ? 'SET NULL' : 'NO ACTION');
      this.options.onUpdate = this.options.onUpdate || 'CASCADE';
    }

    Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.target, this.source, this.options, this.targetKeyField);
    Utils.mergeDefaults(this.source.rawAttributes, newAttributes);

    this.identifierField = this.source.rawAttributes[this.foreignKey].field || this.foreignKey;

    this.source.refreshAttributes();

    Helpers.checkNamingCollision(this);

    return this;
  }

  mixin(obj) {
    const methods = ['get', 'set', 'create'];

    Helpers.mixinMethods(this, obj, methods);
  }

  /**
   * Get the associated instance.
   *
   * @param {Object} [options]
   * @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false.
   * @param {String} [options.schema] Apply a schema on the related model
   * @see {@link Model.findOne} for a full explanation of options
   * @return {Promise<Model>}
   */
  get(instances, options) {
    const association = this;
    const where = {};
    let Target = association.target;
    let instance;

    options = Utils.cloneDeep(options);

    if (options.hasOwnProperty('scope')) {
      if (!options.scope) {
        Target = Target.unscoped();
      } else {
        Target = Target.scope(options.scope);
      }
    }

    if (options.hasOwnProperty('schema')) {
      Target = Target.schema(options.schema, options.schemaDelimiter);
    }

    if (!Array.isArray(instances)) {
      instance = instances;
      instances = undefined;
    }

    if (instances) {
      where[association.targetKey] = {
        [Op.in]: instances.map(instance => instance.get(association.foreignKey))
      };
    } else {
      if (association.targetKeyIsPrimary && !options.where) {
        return Target.findByPk(instance.get(association.foreignKey), options);
      } else {
        where[association.targetKey] = instance.get(association.foreignKey);
        options.limit = null;
      }
    }

    options.where = options.where ?
      {[Op.and]: [where, options.where]} :
      where;

    if (instances) {
      return Target.findAll(options).then(results => {
        const result = {};
        for (const instance of instances) {
          result[instance.get(association.foreignKey, {raw: true})] = null;
        }

        for (const instance of results) {
          result[instance.get(association.targetKey, {raw: true})] = instance;
        }

        return result;
      });
    }

    return Target.findOne(options);
  }

  /**
   * Set the associated model.
   *
   * @param {Model|String|Number} [newAssociation] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association.
   * @param {Object} [options] Options passed to `this.save`
   * @param {Boolean} [options.save=true] Skip saving this after setting the foreign key if false.
   * @return {Promise}
   */
  set(sourceInstance, associatedInstance, options) {
    const association = this;

    options = options || {};

    let value = associatedInstance;
    if (associatedInstance instanceof association.target) {
      value = associatedInstance[association.targetKey];
    }

    sourceInstance.set(association.foreignKey, value);

    if (options.save === false) return;

    options = _.extend({
      fields: [association.foreignKey],
      allowNull: [association.foreignKey],
      association: true
    }, options);

    // passes the changed field to save, so only that field get updated.
    return sourceInstance.save(options);
  }

  /**
   * Create a new instance of the associated model and associate it with this.
   *
   * @param {Object} [values]
   * @param {Object} [options] Options passed to `target.create` and setAssociation.
   * @see {@link Model#create}  for a full explanation of options
   * @return {Promise}
   */
  create(sourceInstance, values, fieldsOrOptions) {
    const association = this;

    const options = {};

    if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
      options.transaction = fieldsOrOptions.transaction;
    }
    options.logging = (fieldsOrOptions || {}).logging;

    return association.target.create(values, fieldsOrOptions).then(newAssociatedObject =>
      sourceInstance[association.accessors.set](newAssociatedObject, options)
    );
  }
} called with something that's not a subclass of Sequelize.Model
    at Function.<anonymous> (E:...\Projects\WebApps\hr1\hr1\node_modules\sequelize\lib\associations\mixin.js:81:13)
    at Object.<anonymous> (E:...\Projects\WebApps\hr1\hr1\models\user_employee.js:22:14)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (E:...\Projects\WebApps\hr1\hr1\models\user.js:4:26)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (E:...\Projects\WebApps\hr1\hr1\routes\index.js:4:12)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)

这是我的代码

model/User.js

model/User.js

var bcrypt =  require('bcrypt');
const sequelize = require('../config/connectionDatabase')
var Sequelize = require('sequelize');
const UserEmployee = require('../models/user_employee');

var User = sequelize.define('user_tm', {
    NameFirst: {
        type: Sequelize.STRING
    },
    NameLast: {
        type: Sequelize.STRING
    },
    username: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false
    },
    password: {
        type: Sequelize.STRING,
        allowNull: false
    }
}, {
    hooks: {
    beforeCreate: (user) => {
        const salt = bcrypt.genSaltSync();
        user.password = bcrypt.hashSync(user.password, salt);
    }
    },
    instanceMethods: {
    validPassword: function(password) {
        return bcrypt.compareSync(password, this.password);
    }
    }    
});

User.hasOne(UserEmployee, {foreignKey: 'UserID', as: 'User'});
User.prototype.validPassword = function (password) {
    return bcrypt.compareSync(password, this.password);
};
module.exports = User;

model/user_employee.js

model/user_employee.js

const sequelize = require('../config/connectionDatabase');
var Sequelize = require('sequelize');
const User = require('../models/user');

var UserEmployee = sequelize.define('user_employee_tm', {
    DateJoin: {
        type: Sequelize.DATE
    },
    UserID: {
        type: Sequelize.INTEGER,
        references: {
            model: User,
            key: "ID"
        }
    },
    CompanyID: {
        type: Sequelize.INTEGER
    }
});

// UserEmployee.hasOne(User, {as: 'User', foreignKey: 'UserID'});  
UserEmployee.belongsTo(User , {foreignKey: 'ID', as: 'Employee'});
module.exports = UserEmployee;

有什么我想念的吗?我尝试使用此网址 https://dreamdevourer.com/example-of-sequelize-associations-in -feathersjs/

is there something I missed of? I've try to use this url https://dreamdevourer.com/example-of-sequelize-associations-in-feathersjs/

用于与模型一起添加关联,但仍然存在相同的问题.

for adding assosicate along with model, but still having the same problem.

非常感谢您的帮助

推荐答案

结果发现我只需要定义UserEmployee对象 这是我已修复的代码

Turns out I've found that I just need to define my Object of UserEmployee Here's the code that I've Fixed

const sequelize = require('../config/connectionDatabase');
var Sequelize = require('sequelize');
const User = require('../models/user');
const Company = require('../models/company');

var UserEmployee = sequelize.define('user_employee_tm', {
    DateJoin: {
        type: Sequelize.DATE
    },
    UserID: {
        type: Sequelize.INTEGER,
        references: {
            model: User,
            key: "UserID"
        }
    },
    CompanyID: {
        type: Sequelize.INTEGER,
        references: {
            model: Company,
            key: "CompanyID"
        }
    }
});
UserEmployee.belongsTo(Company, {as: 'Company', foreignKey: 'CompanyID'});
UserEmployee.belongsTo(User, {as: 'User', foreignKey: 'UserID'});
module.exports = UserEmployee;

由于Sequelize已设置了将它们关联的方法,因此无需将其设置为关联,并且我也已修复了它们之间的关系.

no need to set as associate due to Sequelize has set method associate them, and I've also fix the relation of it.

希望其他与我有相同问题的人也可以照看它,而不会使2个模型最终存储在1个文件中.

hope others that has same problem with me could look after it, without make 2 models ends up on 1 file.

P.S. 感谢doublesharp对您指出我的错误做法提供的帮助

P.S. Thanks for doublesharp for your help to point my wrong doing

这篇关于调用了Sequelize Assosication而不是Sequelize.Model的子类的东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆