2013-02-25 11 views
14

Mam dziwny problem, który mnie niepokoi. Mam model:Nie można zaktualizować modelu mangusty

var Model = new Schema({ 
    name: String, 
    variations: Array 
}); 

Wpis odmiany wygląda tak:

[ {code: '', price: '' }, {code: '', price: '' }] 

muszę dodawać nowe pole - mówią "kolor". Więc robię to do aktualizacji serii:

Model.find().exec(function(err, products) { 
    if (!err) { 
     products.forEach(function(p) { 
      for(var i = p.variations.length - 1; i >= 0; i--) { 
       p.variations[i]['color'] = 'red'; 
       // This shows all existing variations 
       // with the new color feed - correct 
       console.log(p.variations[i]); 
      } 
      p.save(function(err) { 
       if (!err) { 
        console.log("Success"); 
       } else { 
        console.log(err); 
       } 
      }); 
     });  
    } 
}); 

Jednak „kolor” pole nie jest ustawiony - gdybym przejść ponownie i skomentuj linię p.variations[i]['color'] = 'red'; to nie wskazuje. Nie mogę się domyślić, dlaczego to robi. Mam zdarzenie onSave, które jest uruchamiane poprawnie, więc jest zapisywane. Nie mam też żadnej kontroli struktury zmian - tzn. Nie ma kodu, który pozwala tylko na kod i cenę. Najwyraźniej czegoś brakuje, ale po kilku godzinach zabrakło mi pomysłów.

Odpowiedz

26

Podczas modyfikowania zawartości pozbawionym typu Array dziedzinie jak variations, trzeba zawiadomić Mongoose że zmieniłeś swoją wartość poprzez wywołanie markModified(path) na zmodyfikowanej dokumentu lub późniejszej save() rozmowy nie będzie go zapisać. See docs.

for(var i = p.variations.length - 1; i >=0; i--) { 
    p.variations[i]['color'] = 'red'; 
    } 
    p.markModified('variations'); 
    p.save(function(err) { ... 
+0

Dotyczy to również użycia głębokich obiektów z luźnym typem schematu (mangusta.Schema.Types.Mixed). A od Mongoose 4.5.8 powyższa metoda (markModified) nadal jest metodą działającą w tym kierunku. – SylonZero

3

Musisz użyć funkcji set zmienić właściwość. Wynika to z tego, że mangusta musi oznaczyć to pole jako zmodyfikowane w celu zapisania w bazie danych.

for(var i = p.variations.length - 1; i >=0; i--) { 
    p.variations[i].set({"color":"red", "code":"herr"}); 
    // or 
    p.variations[i].set("color":"red"); 
    p.variations[i].set("code":"herr"); 
} 

Alternatywą byłoby zmienić wartość pola po staremu, bez przechodzenia trought setter, a następnie ręcznie oznaczyć go jako modyfikacja: p.markModified('variations');

Moim zdaniem należy zawsze używać setter, ponieważ jest to bardziej czytelny. Możesz po prostu przekazać obiekt json zawierający wszystkie zmiany w parametrze i bezpiecznie zaktualizuje pola, które chcesz zmienić.

Powiązane problemy