在Sails.js中使用一个请求创建/更新多个记录

时间:2015-04-05 11:59:07

标签: node.js post promise sails.js waterline

我想知道在一个请求中创建/更新多个记录的最佳做法是什么。我知道我们可以使用Promise.all()来做到这一点。但是如果我想告诉客户哪些记录成功哪些失败了呢?

例如,用户发布的内容如下:

{
    departmentId: 1,
    students: [
                  {name: 'John', studentId: 123},
                  {name: 'Mike', studentId: 124},
              ]
}

我目前的解决方案是:

StudentController:

var departmentId = req.param('departmentId');
var postStudents = req.param['students'];

var department;
var failedRecords = [];
Department.findOne()
    .then(function (_department) {
        department = _department;
        var students = [];
        while (postStudents.length) {
            var student = postStudents.pop();
            student.department = departmentId;
            var s = Student.create(s)
                        .then(function(s){return s;})
                        .catch(function(e){ failedRecords.push(student)}); // A closure problem happens here
            students.push(s);
        }
        return students;
    })
    .each(function (student) {
        department.students.add(student[0].id);
        return department.save().catch(function(e){/* log: add to department failed */});
    })
    .then(function () {
        return res.json({msg: "Success"});
    })
    .catch(function (e) {
        return res.json(404, {err: "Fail", records: failedRecords});
    });

代码很丑,我也省略了代码来解决while循环中的闭包问题。另外,我不知道如何在第二次捕获中保存到失败的记录。

3 个答案:

答案 0 :(得分:3)

您应该只需运行以下内容即可为学生生成记录。有关详情,请参阅waterline-orm/models/create

// create the students
var students = [{name: 'John', studentId: 123},{name: 'Mike', studentId: 124}];
Student.create(students).exec(function createCB(err, created){
  console.log('Created student with name ' + created[0].name);
  console.log('Created student with name ' + created[1].name);
  //Do other stuff here.
});

答案 1 :(得分:1)

我猜Sails使用Q库。如果没有,您可以使用Q.()将任何承诺转换为Q.

那么,您是否看过Q.all()

,而不是Q.allSettled()方法

以下是两种方法(from the Q library guide)的区别:

  

all函数返回值数组的promise。当履行此承诺时,数组包含原始承诺的履行值,其顺序与承诺相同。如果其中一个给定的承诺被拒绝,则立即拒绝返回的承诺,而不是等待批次的其余部分。如果您想等待所有承诺要么被履行或被拒绝,您可以使用allSettled。

Q.allSettled()将等待所有承诺完成,即使一个或多个被拒绝,并返回一个对象数组,如: { state: "fulfilled", value: v } or { state: "rejected", reason: r }

API Reference - promise.allSettled()

我不确定这是否是插入数据库的最佳做法,因为水线可能有批量插入模式。但是我已经以这种方式完成了发布到API以插入记录并为我工作正常。

答案 2 :(得分:1)

您需要createEach()

这是我项目的代码示例。

  

控制器\ FilesController.js

module.exports = {
  upload: function (req, res) {

    req.file('files').upload({
        dirname: require('path').resolve(sails.config.appPath, 'Files')
      },
      function (err, files) {
        if (err) {
          return res.serverError(err);
        }

        var array = [];
        files.forEach(file => {
          data = {
            name: file.filename,
            size: file.size,
            md5: 'd41d8cd98f00b204e9800998ecf8427e',
            uploaded_by: req.user.id
          }

          array.push(data)

        });


        Files.createEach(array).fetch().exec(function (err, user) {
          if (err) return res.serverError(err);
          sails.log(user)
        })

        res.json({
          "Status": files.length + " file(s) uploaded successfully!",
          "Files": files,
        });

      })

  },

};