2014-12-03 40 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