如何填充序列化关联-编辑

时间:2019-05-19 16:23:42

标签: node.js sequelize.js

我第一次尝试使用Sequelize,但是在阅读文档,博客和问题数小时后,我仍然感到困惑,需要一些帮助以正确的方式了解协会的工作方式。 这就是我所做的:

EDIT :我从模型中删除了 associate 函数,因为该函数仅适用于index.js like this。我在sync()之前直接在index.js中定义关联。在查询sqlite模式之后,确认将 UserId 字段添加到表中。

数据库连接模块

const Sequelize = require('sequelize');
const db = new Sequelize({
  host: 'localhost',
  dialect: 'sqlite',
  storage: './nodeapp.db.sqlite'
});    
db
  .authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
    db.models.User.hasMany(db.models.Order);
    // db.models.Order.belongsTo(db.models.User); // THIS WORKS TOO
    db.sync();
    console.log('Database synchronized successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });
module.exports = db;

用户模型定义

const DataTypes = require('sequelize');
const db = require('./index');
const User = db.define('User', {
    username: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
   },
...
});
/* REMOVED
User.associate = (models) => {
  models.User.hasMany(models.Order);
};
*/
module.exports = User;

订单模型定义

const DataTypes = require('sequelize');
const db = require('./index');
const Order = db.define('Order', {
  order_num: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true
  },
...
});
/* REMOVED
Order.associate = (models) => {
  models.Order.belongsTo(models.User);
};
*/
module.exports = Order;

路由器模块

router.post('/order',(req,res) => {
  Order
    .create(req.body.order)
    .then(order => {

      // HERE IS WHERE I'AM TRYING TO POPULATE THE RELATION WITH SET ...
      order.setUser(req.body.user).then((order) => {
        res.send(order);
      })          

  .catch(error => {
    res.send(error);
  });
});

如果我不考虑这种关系,那么所有CRUD操作都可以正常工作。我无法弄清楚如何在订单模型中填充用户参考,我的问题是: -在模型中定义关联仅添加外键字段? -我必须手动用ID值填充外键,否则我可以使用用户对象?

我需要一些帮助来确定我在哪里出错了,因为我知道我没有做新的事情。

3 个答案:

答案 0 :(得分:1)

  1. 您必须在模型定义中声明一个主键:

    const User = db.define('User', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
      },
      username: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
       }
    });
    
    const Order = db.define('Order', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
      },
      userId: {
        type: Sequelize.INTEGER,
      },
      order_num: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
      }
    });
    
  2. 您必须在迁移文件中包括所有字段,包括主键和外键。

    module.exports = {
      up: function(queryInterface, Sequelize) {
        return queryInterface.createTable('orders', {
              id: {
                type: Sequelize.INTEGER,
                primaryKey: true,
                autoIncrement: true,
              },
              userId: {
                type: Sequelize.INTEGER,
              },
              order_num: {
                type: DataTypes.STRING,
                allowNull: false,
                unique: true
              }
        });
      },
    
      down: function(queryInterface) {
        ...
      }
    };
    
  3. 请记住,ORM操作是异步的。考虑使用asyc/await

    router.post('/order', async (req,res) => {
      Order
        .create(req.body.order)
        .then(order => {
    
          // you must fetch the user instance from req.user.id
          const userInstance = models.User.findByPk(req.user.id)
    
          // HERE IS WHERE I'AM TRYING TO POPULATE THE RELATION WITH SET ...
          await order.setUser(userInstance, {save: false});
          order.save();
          res.send(order);
        })
      .catch(error => {
        res.send(error);
      });
    });
    

答案 1 :(得分:0)

由于有了一些评论和类似的问题,我终于使它起作用了。目前,我发现自己的错误非常有用this piece of documentation。 我的错误在于数据库的定义,可能这不是最佳解决方案,但我正在努力解决,任何建议或最佳实践都将被接受。

数据库连接模块

...
db
.authenticate()
.then(() => {
  console.log('Connection has been established successfully.');
  const User = require('./user');
  const Account = require('./account');
  const Order = require('./order');
  // At this point all models needed for associations are defined
  Account.belongsTo(User);
  Order.belongsTo(User);
  Order.belongsTo(Account);
  Order.belongsTo(Account, {as: 'Shipto'});
  Order.belongsTo(Account, {as: 'Billto'});
  db.sync();
  console.log('Database synchronized successfully.');
})
...

模型定义文件保持不变。

路由器模块

router.post('/order',(req,res) => {
 db.models.Order
 .create(req.body.order)
 .then((order) => {
   order.setUser(req.body.order.UserId);
   order.setAccount(req.body.order.AccountId);
   order.setShipto(req.body.order.ShiptoId);
   order.setBillto(req.body.order.Billtoid);
   res.send(order);
 })
 .catch(error => {
   res.send(error);
 });
});

答案 2 :(得分:-1)

我认为您需要创建这样的关联,我的模型中有这些关联,并且它们工作正常。

因此只需更改关联

User.associate = (models) => {
  models.User.hasMany(models.Order);
};

对此,

User.associate = (models) => {
  User.hasMany(models.Order, { foreignKey: 'user_id' });
};