hasMany调用的东西不是Sequelize.Model

时间:2017-05-19 12:59:25

标签: node.js postgresql sequelize.js

因为你们可以看到我的问题与标题描述有关,我创建了一个用户模型和一个续集的Foto模型,基本上用户可以拍摄许多照片,但每个照片只能与1个用户相关。 / p>

我的用户模型

    "use strict";
var sequelize = require('./index');
var bcrypt = require('bcrypt-nodejs');
var Foto = require('./Foto');

module.exports = function (sequelize, DataTypes) {
  var User = sequelize.define("User", {
    username: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isUnique: function (value, next) {
          var self = this;
          User.find({ where: { username: value } })
            .then(function (user) {
              // reject if a different user wants to use the same username
              if (user && self.id !== user.id) {
                return next('username already in use!');
              }
              return next();
            })
            .catch(function (err) {
              return next(err);
            });
        }
      }
    },

    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isUnique: function (value, next) {
          var self = this;
          User.find({ where: { email: value } })
            .then(function (user) {
              // reject if a different user wants to use the same email
              if (user && self.id !== user.id) {
                return next('Email already in use!');
              }
              return next();
            })
            .catch(function (err) {
              return next(err);
            });
        }
      }
    },

    typeOfUser: {
      type: DataTypes.INTEGER,
      allowNull:true,
      defaultValue:null
    },

    country: {
      type: DataTypes.STRING,
      allowNull:true,
      defaultValue:null
    },

    birthDate:{
      type: DataTypes.DATEONLY,
      allowNull:true,
      defaultValue:null
    },

    reports: {
      type: DataTypes.INTEGER,
      defaultValue: 0
    },

    points: {
      type: DataTypes.INTEGER,
      defaultValue: 0
    },

    password: {
      type: DataTypes.STRING,
      allowNull:false
    },

    numberFotos: {
      type: DataTypes.INTEGER,
      defaultValue: 0
    }
  }, {
      classMethods: {
        generateHash: function (password) {
          return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
        },

      },
      instanceMethods: {
        validPassword: function (password) {
          return bcrypt.compareSync(password, this.password);
        }
      }


    });

  User.hasMany(Foto,{as: 'fotos', foreignKey: 'userId'})

  return Foto;
}

我的照片模型

"use strict";
var sequelize = require('./index');
var bcrypt = require('bcrypt-nodejs');
var User = require('./User');


module.exports = function (sequelize, DataTypes) {
  var Foto = sequelize.define("Foto", {
    reports: {
      type: DataTypes.INTEGER,
      defaultValue: 0
    },
    image: {
      type: DataTypes.STRING,
      allowNull: false
    },
    date: {
      type: DataTypes.DATE,
      allowNull:true
    },
    position: {
      type: DataTypes.RANGE,
      allowNull: true
    }
  });

  Foto.belongsTo(User, {foreignKey: 'userId'});

  return Foto;
}

7 个答案:

答案 0 :(得分:11)

您不需要在照片模型上声明关联:

Foto.belongsTo(User, {foreignKey: 'userId'});

如果模型之间有1:N关系,则只需要参考" 1"模型,在我们的案例中是用户模型,在" N"模特,照片。这样做:

User.hasMany(Foto,{as: 'fotos', foreignKey: 'userId'})

将在您的Foto表格上创建一个名称为" userId"引用用户表。通过这种方式,两个模型都可以根据需要进行关联。

答案 1 :(得分:7)

我有类似的问题。有时可能是由于在index.js或app.js中文件以特定顺序加载导致的,例如,如果您在A和B之间有关系,A首先加载并且引用B,而B又引用A ,由于A尚未完全定义/执行,该错误将被抛出到B文件中。

解决方案是从模型文件中删除所有关联,并在您的应用或index.js内部将它们全部都删除,然后定义它们之间的关系。

示例

const entities = {
  A: require('./src/Entity/A'),
  B: require('./src/Entity/B'),
};
entities.A.belongsToMany(entities.B, {through: 'AB'});
entities.B.belongsToMany(entities.A, {through: 'AB'});

答案 2 :(得分:2)

所以我遇到了这个错误,我花了一些时间来解决这个错误。我意识到我得到了错误,因为我错误地引用了模型。 Sequelize区分大小写,因此,如果使用UpperCase创建模型,请确保在整个引用过程中保持一致。

我还要指出您可以尝试一下

 User.hasMany(models.Foto ,{as: 'fotos', foreignKey: 'userId'})

答案 3 :(得分:1)

似乎您需要在包含1:many关联的1部分的文件中定义关系的两端。也就是说,您所用的“用户”文件。

所以:

User.hasMany(Foto); Foto.belongsTo(User);

答案 4 :(得分:0)

您可以在一个文件中定义两个模型的关系。这样不会引发任何错误。

在Foto.js中,您可以尝试:

...

Foto.belongsTo(User);
User.hasMany(Foto);

return Foto;

答案 5 :(得分:0)

以上解决方案均不适用于我的情况(可能适用于其他设置)。我偶然发现了这篇文章,指出您必须在应用关联之前定义和导出模型。使用单独的extra-setup.js文件定义关联对我有用。

https://github.com/sequelize/express-example/tree/master/express-main-example

答案 6 :(得分:0)

我遇到了很多问题,但我转而使用以这种格式生成模型的 sequelize CLI,然后我发现创建关联要容易得多,因为索引文件处理了所有事情以及其中的 static associate({ PersonalDetail })模型本身已经在一个地方需要你的模型,你需要做的就是解构它们,所以不需要文件顶部的任何东西。

这个 YouTube 视频对我很有帮助...https://www.youtube.com/watch?v=3qlnR9hK-lQ

'use strict'
const { Model } = require('sequelize')
module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate({ PersonalDetail }) {
      // define association here
      this.hasMany(PersonalDetail, {
        foreignKey: 'userId',
        //as: 'personalDetails',
      })
    }
  }
  User.init(
    {
      uuid: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
      },
  
      moredata below: {
        type: DataTypes.STRING,
        allowNull: false,
      },

      //createdAt/updatedAt is defined in migration and updated automatically
    },
    {
      sequelize,
      tableName: 'users',
      modelName: 'User',
    }
  )
  return User
}