【问题标题】:SailsJS, Waterline populate records with selectSailsJS,Waterline 使用选择填充记录
【发布时间】:2019-09-01 05:02:48
【问题描述】:

我查看了很多旧的 SO 问题,它们破坏了 GitHub 链接和 SailsJS Trello,但我仍然不清楚。

是否可以在 SailsJS 中填充字段(一对一关系)并仅返回特定字段(通过选择或省略)。

await Document.find({id: id}).populate('createdBy', {select: ['name']})

我来了

UsageError: Invalid populate(s).
Details:
  Could not populate `createdBy` because of ambiguous usage.  This is a singular ("model") association, which means it never refers to more than _one_ associated record.  So passing in subcriteria (i.e. as the second argument to `.populate()`) is not supported for this association
, since it generally wouldn't make any sense.  But that's the trouble-- it looks like some sort of a subcriteria (or something) _was_ provided!
(Note that subcriterias consisting ONLY of `omit` or `select` are a special case that _does_ make sense.  This usage will be supported in a future version of Waterline.)

Here's what was passed in:
{ select: [ 'name' ] }

在模型中,

createdBy: {
      model: 'user',
      description: 'Who is this document assigned to'
    },

我正在使用风帆1.1.0,水线0.13.5-0

我这样做对吗?有没有办法做到这一点?

【问题讨论】:

    标签: orm sails.js waterline


    【解决方案1】:

    我解决了问题并提出了拉取请求。由于拉取请求尚未被接受,请小心并在您的请求中使用它。

    前往

    node_modules/waterline/lib/waterline/utils/query/forge-stage-two-query.js

    转到此部分

    // If this is a singular ("model") association, then it should always have
    // an empty dictionary on the RHS.  (For this type of association, there is
    // always either exactly one associated record, or none of them.)
    if (populateAttrDef.model) {....}
    

    改成:

         if (populateAttrDef.model) {
    
            // Tolerate a subcriteria of `{}`, interpreting it to mean that there is
            // really no criteria at all, and that we should just use `true` (the
            // default "enabled" value for singular "model" associations.)
            if (_.isEqual(query.populates[populateAttrName], {})) {
              query.populates[populateAttrName] = true;
            }
            // Otherwise, this simply must be `true`.  Otherwise it's invalid.
            else {
    
              if (query.populates[populateAttrName] !== true && (_.isUndefined(query.populates[populateAttrName].select) && _.isUndefined(query.populates[populateAttrName].omit))) {
                throw buildUsageError(
                  'E_INVALID_POPULATES',
                  'Could not populate `'+populateAttrName+'` because of ambiguous usage.  '+
                  'This is a singular ("model") association, which means it never refers to '+
                  'more than _one_ associated record.  So passing in subcriteria (i.e. as '+
                  'the second argument to `.populate()`) is not supported for this association, '+
                  'since it generally wouldn\'t make any sense.  But that\'s the trouble-- it '+
                  'looks like some sort of a subcriteria (or something) _was_ provided!\n'+
                  '(Note that subcriterias consisting ONLY of `omit` or `select` are a special '+
                  'case that _does_ make sense.  This usage will be supported in a future version '+
                  'of Waterline.)\n'+
                  '\n'+
                  'Here\'s what was passed in:\n'+
                  util.inspect(query.populates[populateAttrName], {depth: 5}),
                  query.using
                );
              }//-•
              else {
                query.populates[populateAttrName] = {
                  select: query.populates[populateAttrName].select? query.populates[populateAttrName].select : undefined,
                  omit: query.populates[populateAttrName].omit? query.populates[populateAttrName].omit : undefined
                };
              }
    
            }//>-•
    
          }
    

    这是查看您应该更改的确切内容的拉取请求: https://github.com/balderdashy/waterline/pull/1613

    【讨论】:

      【解决方案2】:

      当您使用一对一关联时,您不能使用诸如错误之类的子标准。

      So passing in subcriteria (i.e. as the second argument to `.populate()`) is not supported for this association
      

      你可以在模型createdBy上使用customToJSON函数来省略数据。

      customToJSON: function() {
      
        return _.omit(this, ['createdAt', 'updatedAt', 'id'])
      }
      

      【讨论】:

      • 使用 find() 函数时会触发 cutomToJson 函数吗?我已将它添加到 Document 和 User 模型中,但它根本没有被触发。事实上,即使是 User.findOne({id: id}) 也会返回完整的记录,包括省略的字段。
      • 功能设置好了吗? { attributes: {}, customToJSON: function () {    return _.omit (this, ['createdAt', 'updatedAt', 'id']) } }
      • 是的,这正是它的设置方式(attributes 包含字段)。我一直在尝试调试它,但没有运气
      • 使用 customToJSON 方法,整个记录将从数据库返回,但是当从控制器返回一些 JSON 响应时(即exits.success({ records: theReturnedRecords }),它应该在发送 HTTP 响应之前运行。这是半对于诸如不意外分发用户密码之类的事情很有用,但在这里可能没有那么多。正如 Sails/Waterline 生成的警告所说的关于您最初使用 select 的情况:“未来版本的 Waterline 将支持这种用法”
      • customToJSON: function 不要省略数据库中的记录,当模型使用 JSON.stringify() 时会触发,请查看文档link。因此,当您使用 res.json(data)、res.send() 或如果您使用 actions2 exists.success(data) 时,它将触发函数 .toJSON() 并且此函数使用 customToJSON 设置。您是否看到响应中的省略字段?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      • 2014-07-30
      相关资源
      最近更新 更多