Как использовать Sequelize моделей миграции при запросах? - PullRequest
0 голосов
/ 05 января 2019

Я недавно переключился с "нормального" sequelize на миграции с sequelize-cli. Использование cli до сих пор работало нормально. Но я не уверен, как использовать созданные модели. В частности, кажется, что, как я это делаю, у меня проблемы с ассоциациями. Они правильно созданы в базе данных, но в коде я получаю ошибки типа Upvote is not associated to Video

Я создал модели с помощью cli и попытался импортировать и использовать их.

Это фрагмент модели video, сгенерированной командой cli:

module.exports = (sequelize, DataTypes) => {
    const Video = sequelize.define('Video', {
        userid: DataTypes.STRING,
        ...
    }, {});
    Video.associate = function(models) {
        Video.hasMany(models.Upvote, { foreignKey: 'videoid', sourceKey: 'id' });
    };
    return Video;
};

Вот фрагмент миграции:

let videos = function (queryInterface, Sequelize) {
    return queryInterface.createTable('Videos', {
        id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER
        },
        userid: {
            type: Sequelize.STRING,
            references: {
                model: 'Users',
                key: 'id'
            },
         },
         ...
     });
};

Это способ импорта моделей:

const Video = require('../models/video')(dbConnector.sequelize, Sequelize.DataTypes);

Я нахожу немного странным, что мне нужно пропустить sequelize и DataTypes, так как в этом не было необходимости, когда я сам строил модели. Это правильный способ их импорта? Когда я их импортирую, ошибки нет, и я могу запросить их как Videos.findAll(), но ассоциации не работают. И я не уверен, как заставить их работать, мне нужно самому вызывать функцию Video.associate(models)? Это тоже кажется странным.

Должно быть, я что-то не так делаю, когда использую эти модели, пожалуйста, дайте мне знать, что делать по-другому.

1 Ответ

0 голосов
/ 05 января 2019

Sequelize cli сгенерирует index.js внутри models каталога, который будет иметь следующий код,

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === 
      '.js');
  })
  .forEach(file => {
    const model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

В первом наборе кода он будет импортировать все модели, тогда как во втором наборе он будет связывать все модели на основе ассоциации, настроенной в методе associate каждой модели.

Например, в вашем случае связь между Video и Upvote может быть определена как

модель / Video.js

module.exports = (sequelize, DataTypes) => {
    const Video = sequelize.define('Video', {
        id: DataTypes.STRING,
        ...
    }, {});
    Video.associate = function(models) {
        Video.hasMany(models.Upvote, {
            foreignKey: 'videoId',
            sourceKey: 'id'
        });
    };
    return Video;
};

Модель / Upvote.js

module.exports = (sequelize, DataTypes) => {
    const Upvote = sequelize.define('Upvote', {
        id: DataTypes.STRING,
        videoId: DataTypes.STRING
        ...
    }, {});
    Upvote.associate = function(models) {
        Upvote.belongsTo(models.Video, {
            foreignKey: 'videoId',
            targetKey: 'id'
        });
    };
    return Upvote;
};

Надеюсь, это поможет !!!

...