2015-06-07 13 views
1

模型實例屬性在我們開始之前:我與種子數據和兩個REST端點一個非常小混帳回購協議,以測試在這裏這個問題:https://github.com/juanpasolano/sails-nested-test無法復位sailsjs

所以,我有3種型號:Appointment其中有很多procedure其中有一對一procedureItem。 因爲沒有在船帆我用手使用像越來越proceduresprocedureItem嵌套人口:

Appointment.find(1).exec(function(err, appointments){ 
     if(err) return res.negotiate(err); 
     async.eachSeries(appointments, function(appointment, cb){ 
      Procedure.find({appointment: appointment.id}).populate('procedureItem').exec(function(errP, procedures){ 
       if(errP) return cb(errP); 
       appointment.procedures = procedures; 
       appointment.proceduress = procedures; 
       cb() 
      }) 
     }, function(errE){ 
      if(errE) return cb(errE); 
      res.ok(appointments) 

所以,問題是,當我想更換procedures屬性與新陣列的程序(其中有嵌套深度我需要)它只是沒有設置,如果你點擊演示的端點,沒有procedures屬性可用。
作爲一項測試,我已將相同的新程序數組附加到proceduress(double s)屬性上,並且可以正確設置該屬性。
我已經嘗試使用.toObject()方法沒有運氣。
已嘗試航行0.10.5和0.11.0沒有運氣。

回答

1

是的,沒有程序屬性,如約會有很多程序,所以沒有現場程序DB約會表。所以,如果你不填充,如:

Appointment.find(1).populate('procedures').exec(function(err, appointments){ 
..... 
} 

不會有屬性在任命對象程序

+0

當然。問題是,當我嘗試手動設置程序屬性時,它只是沒有設置。這就是爲什麼我很困惑。請仔細閱讀問題或嘗試演示。我很欣賞時間來回應,但你的回答並不涉及到問題 –

+0

我沒有看到問題,一切正常:http://pastebin.com/A6s9es9L。無論如何,我有三個問題:1.你使用什麼版本的Sails?在你的回購是0.10.5,爲什麼? 2.爲什麼你不會像'Procedure.find({appointment:1})那樣簡單地請求。populate('procedureItem')'? 3.爲什麼你在裏面使用Async和DB請求?做什麼的?如果您有1000條記錄並且生成1000個對數據庫的請求會怎麼樣?如果(errE)返回cb(errE);'如果_errE_不爲null,將會產生一個異常。 – Bulkin

+0

關於異步。如果您需要請求_appointment_的數量,您可以使用* Procedure.find({appointment:[1,2,3]})的語法* populate('procedureItem')並獲取該_appointments_的所有_procedures_一個請求 – Bulkin

1

我有完全相同的問題,前一段時間,我相信這是因爲「程序「屬性被模型使用,無法設置。我最終克隆每一行,然後可以設置值。

更改代碼:

if(err) return res.negotiate(err); 
     var toreturn=_.map(appointments, function(a){ 
      var b=_.clone(a); // so you clone it to a new obj, then you can set the procedure... 
      b.procedures = 'aaaa' 
      return b; 
     }) 
     //res.json(toreturn); // Here you will get appointments with procedures='aaa' 
     async.eachSeries(toreturn, function(appointment, cb){ 
      Procedure.find({appointment: appointment.id}).populate('procedureItem').exec(function(errP, procedures){ 
       if(errP) return cb(errP); 
       appointment.proceduress = procedures; 
       appointment.procedures = procedures; 
       cb() 
      }) 
     }, function(errE){ 
      if(errE) return cb(errE); 
      res.ok(toreturn) 
     }) 

我不知道爲什麼會這樣正好,但是這僅僅是一個解決方案。

在附註中,我可能會建議你而不是爲每個約會做異步,每個約會需要查詢,做兩個大的查找,然後循環合併它們?

事情是這樣的:

var globalApps=[]; 
Appointment.find().then(function(apps){ 
    globalApps=apps; 
    var appIDs=apps.map(function(a){return a.id}); //Get all appointment IDs 
    return Procedure.find({appointment:appIDs}).populate('procedureItem'); 
}).then(function(procs){ //This procs is all procedures match the ids 
    var toReturn =_.map(globalApps,function(a){ 
     var b=_.clone(a); 
     b.procedure=_.find(procs,{appointment:b.id}); // This is O(n^2) complexity matching, but you can do something smart. 
     return b; 
    }); 
    // Now you have toReturn as the appointment array. 
    return res.json(toReturn); 
}) 

我之前花了很多時間在這個問題上,高興有人有同樣的問題

+0

我也很高興別人有這個問題。我不想走你的路,但顯然是唯一的方法。感謝您的答案和關於異步的提示。我希望這在風帆上得到解決。關於模型使用的過程...不是說使用toObject()的目的 –

1

@ sgress454從夢囈這裏。你遇到的問題是procedures屬性不是一個簡單的Javascript變量;它具有「getter」和「setter」,這是必要的,以便讓這些工作:

appointment.procedures.add(<some Procedure obj or id>); 
appointment.procedures.remove(<some Procedure id>); 

所以嘗試,因爲二傳手的設置procedures屬性爲新的值將無法正常工作, 。克隆約會是一個可以接受的解決方法(您可以僅做appointment.toObject()),因爲它將這些特殊屬性轉換爲普通的舊Javascript變量。但就你而言,似乎你並不需要更換procedures陣列 - 你只需要填寫每個程序的procedureItem。而且,由於只有屬性代表許多-to-many關聯有getter和setter,你可以做到這一點沒有任何克隆可言:

Appointment 
    // Find the appointments 
    .find({...some criteria...}) 
    // Populate each appointment's procedure 
    .populate('procedure') 
    .exec(function(err, appointments) { 
     if (err) {return res.negotiate(err);} 
     // Loop through the returned appointments 
     async.each(appointments, function(appointment, appointmentCb) { 
      // For each one, loop through its procedures 
      async.each(appointment.procedures, function(procedure, procedureCb) { 
       // Look up the related procedureItem 
       ProcedureItem.findOne(procedure.procedureItem).exec(function(err, procedureItem) { 
        if (err) {return procedureCb(err);} 
        // Attach the procedureItem object to the procedure 
        procedure.procedureItem = procedureItem; 
        return procedureCb(); 
       }); 
      }, appointmentCb); 
     }, function done(err) { 
      if (err) {return res.negotiate(err);} 
      res.ok(appointments); 
     }); 
    }); 

注意,有一個很大的優化,可以在這裏完成 - 你可以摘下在取回預約後取出所有ProcedureItem ID,一次查找所有ProcedureItem實例,然後將它們映射到過程中,節省大量的查詢。