2012-07-31 40 views
3

我有關於Ember數據和Mongodb嵌入對象的問題。這裏是我的模型:emberdata和mongodb嵌入對象ID undefined

App.Contact = App.Entity.extend({ 
    name    : DS.attr('string'), 
    firstname  : DS.attr('string'), 
    additional_names : DS.attr('string'), 
    civility   : DS.attr('string'), 
    birthday   : DS.attr('date'), 
    organization  : DS.belongsTo('App.Organization'), 
    role    : DS.attr('string'), 
    photo_source  : DS.attr('string'), 
    photo_uri  : DS.attr('string'), 
    gravatar_mail : DS.attr('string'), 
    addresses  : DS.hasMany('App.Address', { embedded: true }), 
    emails   : DS.hasMany('App.Email', { embedded: true }), 
    phones   : DS.hasMany('App.Phone', { embedded: true }) 
}); 

現在我獲取通過API聯繫人:(GET /應用/ API/V1 /聯繫人/ 4f86c4774ab63c2417000001 /)這裏就是我得到:

{ 
    "additional_names": null, 
    "addresses": [], 
    "birthday": null, 
    "civility": null, 
    "emails": [ 
     { 
      "email": "[email protected]", 
      "label": null, 
      "resource_uri": "/app/api/v1/contact/4f86c4774ab63c2417000001/emails/0/", 
      "type": "HOME" 
     } 
    ], 
    "firstname": "Alexandre", 
    "gravatar_mail": null, 
    "groups": [], 
    "id": "4f86c4774ab63c2417000001", 
    "name": "Simoui", 
    "organization": null, 
    "phones": [], 
    "photo_source": null, 
    "photo_uri": "/static/img/nophoto.png", 
    "resource_uri": "/app/api/v1/contact/4f86c4774ab63c2417000001/", 
    "role": null 
} 

我的「根「對象有一個ID,但嵌入對象」電子郵件「沒有。因爲在mongodb中,id不是在子文檔上設置的,而是僅在根文檔上設置的。

這種方式燼數據看到「電子郵件」對象沒有ID,然後它試圖通過API獲取完整的對象。例如:GET/app/api/v1/email/set // 404(NOT FOUND)

爲了確保這是wright問題,我嘗試用僞ID字段返回Mongodb子文檔。喜歡:(看郵件對象的差異)

{ 
    "additional_names": null, 
    "addresses": [], 
    "birthday": null, 
    "civility": null, 
    "emails": [ 
     { 
      "id": 431, 
      "email": "[email protected]", 
      "label": null, 
      "resource_uri": "/app/api/v1/contact/4f86c4774ab63c2417000001/emails/0/", 
      "type": "HOME" 
     } 
    ], 
    "firstname": "Alexandre", 
    "gravatar_mail": null, 
    "groups": [], 
    "id": "4f86c4774ab63c2417000001", 
    "name": "Simoui", 
    "organization": null, 
    "phones": [], 
    "photo_source": null, 
    "photo_uri": "/static/img/nophoto.png", 
    "resource_uri": "/app/api/v1/contact/4f86c4774ab63c2417000001/", 
    "role": null 
} 

然後我沒有問題一切都很好。所以我的問題是:有沒有辦法解決它?

+0

如果你已經解決了這個,你介意張貼你如何去了解它。 – brg 2012-08-17 11:52:33

+0

你有沒有得到這個工作? – albertjan 2013-01-15 09:46:22

+4

查看最新版本的ember-data,發生了很多變化。 Ember-data現在支持沒有ID的嵌入記錄。 – ThomasDurin 2013-01-15 12:47:51

回答

3

我已經開始嘗試一種解決方法。我只使用沒有ID的嵌入式對象,因此我沒有測試過保存,創建和適當的模型狀態管理(isDirty等)......但是到目前爲止,這已經解決了我的類似問題。

不幸的是我需要修改的燼數據源。請參閱ember-data的my fork

我改變的程度涉及修改DS.hasManyhasAssociation()函數。我所做的是在訪問關聯的計算屬性第一次返回時注入僞ID。我在閉包中保存了一個客戶端ID計數器injectedIdCounter,該閉包定義了hasAssociation()以及一個獲取ID並更新計數器的函數。然後我定義一個新選項trueEmbedded這是一個沒有ID的嵌入式子文檔。每次在關聯上調用get()時,都會檢查元素的ID,如果ID不存在,則注入元素。如果添加了ID,則需要調用set(),以便修改的關聯存儲在父對象上。至少這解決了我的問題。這是我的代碼。

var injectedIdCounter = 1; 
var getInjectedId = function() { 
    return injectedIdCounter++; 
}; 

var hasAssociation = function(type, options) { 
    options = options || {}; 

    var embedded = options.embedded, 
     findRecord = embedded ? embeddedFindRecord : referencedFindRecord; 

    var meta = { type: type, isAssociation: true, options: options, kind: 'hasMany' }; 

    return Ember.computed(function(key, value) { 
    var data = get(this, 'data'), 
     store = get(this, 'store'), 
     ids, id, association; 

    if (typeof type === 'string') { 
     type = get(this, type, false) || get(window, type); 
    } 

    key = options.key || get(this, 'namingConvention').keyToJSONKey(key); 
    if (options.trueEmbedded) { 
     association = get(data, key); 
     var injectedIdCount = 0; 
     association.forEach(function(item) { 
     if (Ember.none(item.id)) { 
      item.id = getInjectedId(); 
      injectedIdCount++; 
     } 
     }); 
     if (injectedIdCount > 0) { 
     set(data, key, association); 
     } 
     ids = embeddedFindRecord(store, type, data, key); 
    } else { 
     ids = findRecord(store, type, data, key); 
    } 
    association = store.findMany(type, ids || []); 
    set(association, 'parentRecord', this); 

    return association; 
    }).property().cacheable().meta(meta); 
}; 

你會認爲,嵌入文檔並不需要一個ID,但灰燼方式,數據首先抓取對象的所有的ID,然後對象本身,即使是一個嵌入式的關聯,意味着一些這樣的混亂的解決方案是必需的。

希望這將在未來的Ember版本中得到修復。

乾杯, 凱文