Sails 0.10关联无法填充

时间:2014-03-07 18:48:57

标签: node.js sails.js waterline

我正在使用sails@0.10.0-rc4中的自定义适配器,它将支持关联,但我无法让它们与我的适配器一起工作。我的配置是文章和统计信息之间的一对多关联。我的模型和适配器设置如下:

// api/models/article.js
module.exports = {
  connection: ['myadapter'],
  tableName: 'Knowledge_Base__kav',
  attributes: {
    KnowledgeArticleId: { type: 'string', primaryKey: true }
    stats: {
      collection: 'stats',
      via: 'parentId'
    } 
  }

// api/models/stats.js
module.exports = {
  connection: ['myadapter'],
  tableName: 'KnowledgeArticleViewStat',
  attributes: {
    count: 'integer',
    ParentId: {
      model: 'article'
    }
  }
}


// adapter.js  
find: function(connectionName, collectionName, options, cb) {  
  console.dir(options)
  // output
  // {where: null} 
  db.query(options, function(err, res)) {
    cb(err, res)
  }
}

但是,当我尝试使用Article.find().populate('stats').exec(console.log())进行填充时,我的适配器会在我希望它接收{where: null}时获取{where: {parentId: [<some-article-id>]}}作为选项。它向我返回一个文章列表,但是应该从另一个模型(统计数据)填充的字段只是一个空列表。

我觉得这与我的适配器没有得到正确的param来搜索主键上的相关模型这一事实有关。为了进一步测试,我使用sails-mongo适配器设置了测试一对多关系。在这种情况下,适配器确实收到了我预期的参数,并且协会工作正常。

有没有人知道为什么.populate('stats')不会向我的适配器发送正确的“where”参数?

更新3/7

所以似乎关联中发生的事情是SomeModel.find()将命中适配器一次,然后.populate('othermodel')再次使用第一个请求的主键命中适配器。然后两者的结果连在一起。在我的情况下,针对适配器的第二次打击不会因某种未知原因而发生。

更新

原始问题与下面评论中提到的属性命名错误有关。但是,particlebanana提到的最终人口步骤似乎仍存在一些问题:

  

最后一步:从所有返回的查询操作中获取所有查询结果   并将它们组合在内存中以构建可以返回的结果集   执行回调。

我发现所有必需的查询现在都在解雇但是他们实际上没有填充别名。以下是使用gist形式添加一些调试输出以便于消费的调用:https://gist.github.com/jasonsims/9423170

2 个答案:

答案 0 :(得分:3)

看起来你走在正确的轨道上!操作集的构建方式,文章上的.find()应该使用第一个日志(空的位置)运行,第二个查询应该使用日志中的parentId条件运行。第二个查询未运行,因为当您不从第一个查询返回任何内容时,它无法构建parentId个主键数组。

简答:您需要在find回调中返回一些内容,以查看第二个日志,该日志应符合您的预期标准。

查询生命周期如下所示:

  • 检查所有查询件是否在同一连接上,如果没有确定哪些查询将在哪些连接上运行
  • 对于单个连接上的所有查询,检查适配器是否支持本机连接(具有.join()方法,如果是,则可以向下传递条件并让适配器处理连接。
  • 如果未定义本机连接方法,请运行&#34; parent&#34;操作(在本例中为Article.find()
  • 使用父操作的结果为需要运行的任何群体建立标准。 (条件中的parentId数组)并运行子结果。
  • 从所有返回的查询操作中获取所有查询结果,并将它们合并到内存中,以构建可在exec回调中返回的结果集。

我希望有所帮助。拍下你的回购的网址,我会仔细查看它,如果它能够开源,如果你遇到任何问题可以帮助更多。

答案 1 :(得分:0)

总而言之,这里发生了多个问题导致关联不能填充:

  1. 自定义主键
    使用自定义主键从模型连接数据时,水线存在问题。 @particlebanana8eff54b修正了这个问题,它应该包含在下一个水线rc中(waterline@0.10.0-rc5)。
  2. 格式错误的SOQL查询
    当waterline第二次查询适配器以获取子行时,它使用{ foreignKey: [ value ] }执行此操作。由于该值是一个列表,因此jsforce错误地生成了SOQL查询,因为它希望所有列表值都伴随$in$nin个运算符。我在github/jsforce#9中解决了这个问题,它现在包含在jsforce@1.1.2。
  3. 模型属性区分大小写
    我的项目中的模型是在snakeCase中定义的,但Salesforce的json响应是使用EveryWordCapitalized。这会导致水线中的1对多连接在运行_.uniq(childRows, pk)时将许多子记录减少为1。由于模型已定义pk == id但从Salesforce返回的实际值为pk == Id,因此对uniq的此调用会清除所有子记录,但会消除一个。我不完全确定这是否应该是水线错误,但修复模型属性定义中的大小写解决了这个问题。