Sails.js 中单个模型的多个表?

Multiple tables for a single model in Sails.js?

我目前有一个用 Perl 编写的网站,使用 Mojolicious and Mojo::Pg。它所做的其中一件事是从我的 Ninja Block 的温度传感器中获取并显示数据。我在 Postgres 中有四个 table,outdoor_temperatureoutdoor_humidity,在室内也是如此。 table 看起来像这样:

 Column |  Type   | Modifiers 
--------+---------+-----------
 time   | bigint  | not null
 value  | numeric | not null
 date   | date    | not null

其中 time 是以毫秒为单位的纪元值(每分钟一条记录),value 是温度或湿度,date 就是这样(所以每条记录一个给定日期在 date 列中具有相同的值)。

我正在使用 Node 和 Sails.js 重写网站,主要是为了学习机会,我有点坚持在这里做事的最佳方式。在它的 Perl 化身中,我为每个与 Ninja Block 相关的功能(显示今天的当前温度,显示给定日期的 highest/lowest 等)都有一个子例程,我传递它的位置(室内或户外),一切都从那里开始,像这样:

sub current {
    my ( $self, $table ) = @_;
    return $self->pg->db->query( "select time, value from $table where time = (select max(time) from $table)" )->hash;
}

但是对于Sails/Waterline,似乎一个模型只包含一个table。在我的 Perl 版本中,任何 table 之间都没有连接,只有一些对每个人 table 的半复杂 SQL 查询,我可以使用 .query 在 Sails 中完成这些查询,但我不确定如何在 Sails 下保留相同的设置,而无需在检查室内和室外时复制一堆代码 tables.

还是我完全错误地考虑了这个问题,有更好的方法来完成这一切?

我最终选择了一个位于控制器和模型之间的服务。控制器函数如下所示(使用与上面相同的示例):

currentTemperature: function(req, res) {
    ninjaBlockService.getCurrentTemperature(req.param('location'), function(data) {
        return res.json(data);
    });
}

以及服务函数:

getCurrentTemperature: function(location, callback) {
    var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";

    var locations = {
        outdoor: function() {
            NinjaBlockOutdoorTemperature.query(query, function(err, results) {
                return callback(results.rows);
            });
        },
        indoor: function() {
            NinjaBlockIndoorTemperature.query(query, function(err, results) {
                return callback(results.rows);
            });
        }
    };

    locations[location]();
}

它可能会更优雅一些,但对我来说效果很好。

因此,事实证明,如果您使用的是 Waterline 的 PostgreSQL 本机 .query,您甚至不需要针对多个 table 的多个模型。我添加了一个名为 NinjaBlock 的新模型,它没有任何属性或任何东西,并且可以 运行 我的查询,无论它们在哪个 table 中。所以上面的函数现在看起来像这样相反:

getCurrentTemperature: function(location, callback) {
    var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";

    NinjaBlock.query(query, function(err, results) {
                return callback(results.rows);
    });
}

简单!