2014-12-03 84 views
3

我正在运行带有postgresql支持的风帆0.10.5,我想询问是否有任何方法可以执行查询以按关系过滤结果。例如:sails.js通过关系查询蓝图

http://api/documents?user.role=Admin 

或者

http://api/documents?where={"user.role": "Admin"} 

或者

http://api/documents?where={"user.role": {"like": "%Admin%"}} 

当一个模型文件有一个属于关联关系的用户,其具有所谓的角色(字符串远东)的属性。

我无法做这样的查询,我错过了什么吗?

谢谢!

回答

1

我不认为现在SailsJS 0.10.5是可能的。其实我想做同样的事情,所以我决定为此目的实施一个快速入侵。

打开文件sails/lib/hooks/blueprints/actionUtil.js,编辑方法populateEach象下面这样:

populateEach: function (query, req) { 
    var DEFAULT_POPULATE_LIMIT = sails.config.blueprints.defaultLimit || 30; 
    var _options = req.options; 
    var aliasFilter = req.param('populate'); 
    var shouldPopulate = _options.populate; 

    // Convert the string representation of the filter list to an Array. We 
    // need this to provide flexibility in the request param. This way both 
    // list string representations are supported: 
    // /model?populate=alias1,alias2,alias3 
    // /model?populate=[alias1,alias2,alias3] 
    if (typeof aliasFilter === 'string') { 
     aliasFilter = aliasFilter.replace(/\[|\]/g, ''); 
     aliasFilter = (aliasFilter) ? aliasFilter.split(',') : []; 
    } 

    return _(_options.associations).reduce(function populateEachAssociation (query, association) {   
     // If an alias filter was provided, override the blueprint config. 
     if (aliasFilter) { 
      shouldPopulate = _.contains(aliasFilter, association.alias); 
     } 

     // Only populate associations if a population filter has been supplied 
     // with the request or if `populate` is set within the blueprint config. 
     // Population filters will override any value stored in the config. 
     // 
     // Additionally, allow an object to be specified, where the key is the 
     // name of the association attribute, and value is true/false 
     // (true to populate, false to not) 
     if (shouldPopulate) { 
      // IMPORTANT NOTE: This is my trick. We should take advanced options from request parameter to make requests even more flexible 
      var populationOptions = req.param('populate_' + association.alias); 

      if (!populationOptions) { 
       var populationLimit = _options['populate_' + association.alias+'_limit'] || 
             _options.populate_limit || 
             _options.limit || 
             DEFAULT_POPULATE_LIMIT; 
       populationOptions = {limit: populationLimit}; 
      } 

      return query.populate(association.alias, populationOptions); 
     } 
     else { 
      return query; 
     } 
    }, query); 
}, 

耶!现在您的API可以处理其他关联过滤器,如下所示:

# POST /api/documents 
{ 
    "where" : { 
     // Normal conditions 
    } 
    "populate_user": { 
     // Advanced condition for association 'admin' 
     "where" : { 
      "role" : { 
       "like": "%Admin%" 
      } 
     }, 
     "limit" : 4  
    } 
} 

我希望它有帮助。顺便说一句,我明天将有时间向SailsJS核心发送这种改进的拉动请求。

P/S:SailsJS核心制作得非常好。核心提交者可能太忙而无法处理所有功能请求。让我们贡献!

+0

嗨小鸭,感谢您的回答,但我不能让它工作。当我按照你的建议做时,我总是会得到'详细信息:错误:列document.populate_user不存在'。此外,我在想一个更通用的解决方案。您可以使用点符号在关系树中导航。我不知道我是否解释得很好。 =/ – Drakson 2014-12-19 07:37:20

+0

您能否提供有关您提出请求方式的更多详细信息? 到目前为止,这个解决方案对我来说工作得非常好。 顺便说一句,如果GET不起作用,请尝试POST(大小写) – Ducky 2014-12-19 08:56:48

+0

它必须是GET请求。 我的请求:'http:// api/documents?populate_user = {其中:{role:'Admin'}}' – Drakson 2014-12-19 10:02:46

0

似乎“人口”在风帆v0.12工作正常。我测试了它的第一级 - 协会和工作正常。但是仍然没有得到一种可用而可靠的方法来获得只有在深度关联中满足特定标准的主导模型记录 - >这是原始问题,甚至在二级或三级深度。编写自定义控制器是现在唯一的方法,或者用更多的逻辑来修改客户端以处理这种“反向”搜索,这就是现在的做法。

首先我找到满足所需条件的关联模型,然后从这个集合中取出“不同”的显性记录标识。它通常意味着对服务器/级别至少有一个或两个以上的请求,因为最终查询具有显性模型ID的“OR”数组。

而且使POST请求某些URL实际得到的数据是不是一个好主意,因为它打破了REST原则的核心是:https://spring.io/understanding/REST