从Sequelize getter方法

时间:2015-10-13 22:52:52

标签: javascript node.js express database-design sequelize.js

这是我在C ++工作20年后的第一个node.js网络应用程序,我想我需要有人指出我在这方面的正确方向。

我正在编写一个与学校和学生打交道的应用程序的服务器端。当客户端(通过我的REST API)为特定学生发送请求时,我想返回学生的姓名和学校。我正在使用一个名为epilogue的库来解析请求,通过sequelize读取/写入MySQL数据库,并将结果包装在JSON响应中。它将发送我为学生定义的所有字段以及我定义的任何getter的值。一切都很好。我已经能够使用结语来POST,PUT,GET并且通常会更新MySQL数据库。

然而,当我尝试定义一个返回学生学校名称的getter方法时,事情变得棘手。为了做到这一点,我必须访问学校表中的记录并获得学校名称。

var school = sequelize.define("School", {
    SchoolName: {
      type: DataTypes.STRING,
    },
  }, {
    classMethods: {
      associate: function(models) {
        school.hasMany(models.Student);
      }
    }
  }
}

var student = sequelize.define("Student", {
    FirstName: {
      type: DataTypes.STRING,
    },
    LastName: {
      type: DataTypes.STRING,
    },
  }, {
    classMethods: {
      associate: function(models) {
        student.belongsTo(models.School);
      },
    },
    getterMethods: {
      FullName: function() {
        return this.FirstName + ' ' + this.LastName; // This works just fine
      },
      SchoolName: function() {
        return this.getSchool().SchoolName; // This doesn't work because getSchool is asynchronous
      }
    }
  }
}

问题是.getSchool()是异步的,所以我似乎必须使用.then来访问结果。承诺对我来说是一个新概念,但我尝试过这样的事情:

SchoolName: function {
  return this.getSchool.then(function(school) {
    return school.SchoolName;
  });
}

但似乎这只是返回Promise本身而不是承诺的结果,因为承诺在getter返回时没有实现。所以,我最终向客户发送了类似的内容:

{
  "FullName": "John Doe", 
  "SchoolName": {
    "isFulfilled": false, 
    "isRejected": false
  },
  "id":1,
  "FirstName":"John",
  "LastName":"Doe"
}

看起来这里的getters必然是同步的,所以看起来我只需要一些方法告诉getter停止并等待Promise完成然后返回值。但这似乎违反了node.js的异步性质。所以,我有一种预感,我从根本上误解了sequelize.js或node.js或promises甚至数据库设计的重要内容。有人可以重定向我吗?主要是,我想知道:正确的方法是做什么的?

1 个答案:

答案 0 :(得分:2)

是的,getSchool()方法返回一个promise。您需要让sequelize查询包含关联。您可以通过创建新的Web服务手动执行此操作并输入您自己的sequelize查询,或者告诉结语如果可以的话。看一下unit test in the epilogue code。也许你可以添加选项:associations: true来加载关联。