web-dev-qa-db-fra.com

Mise à jour séquentielle

J'essaie de mettre à jour un modèle dans Sequelize en utilisant le code suivant:

exports.updateItem = function(item) {
    return new Promise((fulfill, reject) => {
        models.TimesheetItem.update(item,{where: {id: item.id}})
                            .then(fulfill)
                            .catch(console.dir);
     });
};

Où l'élément est le résultat de l'exécution de models.TimeSheetItem.find ()

L'appel n'exécute jamais le .then et passe à la place un objet vide au .catch.

J'ai parcouru la documentation et il semble que c'est la façon de mettre à jour une ligne, mais je ne peux pas la faire fonctionner. Qu'est-ce que je fais mal?

Je vous remercie!

8
troyz

Selon la documentation, la méthode update prend deux paramètres - le premier est values qui sera utilisé pour effectuer la mise à jour, et le second est options - dans votre cas, c'est la clause where. Si vous souhaitez effectuer une mise à jour sur une seule instance uniquement, vous pouvez le faire de deux manières: utilisez la méthode Model.update(), qui peut mettre à jour plusieurs instances de ce modèle simultanément en respectant la clause where ou exécutez instance.update() afin de ne mettre à jour que l'instance unique. La première option ressemblera à ça:

let updateValues = { name: 'changed name' };
models.Model.update(updateValues, { where: { id: 1 } }).then((result) => {
    // here your result is simply an array with number of affected rows
    console.log(result);
    // [ 1 ]
});

La première option n'est pas très utile lorsque vous souhaitez mettre à jour une seule instance. C'est pourquoi il existe une possibilité d'exécuter update() sur l'instance de modèle Sequelize

let updateValues = { name: 'changed name' };
instance.update(updateValues).then((self) => {
    // here self is your instance, but updated
});

Dans votre cas, si le paramètre item est une instance de modèle Sequelize (pas un simple objet JSON Javascript), votre fonction de mise à jour pourrait être comme ça

exports.updateItem = function(item){
    return item.update(values).then((self) => {
        return self;
    }).catch(e => {
        console.log(e);
    });
};

Cependant, si le item n'est pas une instance de modèle séquentielle mais seulement un objet simple avec des valeurs que vous souhaitez mettre à jour, cela pourrait être fait de deux manières - la première consiste à utiliser Model.update() (comme vous l'avez fait), ou la deuxième consiste à récupérer TimesheetItem avec id = item.id puis à exécuter instance.update() comme indiqué ci-dessus

exports.updateItem = function(item){
    models.TimesheetItem.update(item, { where: { id: item.id } }).then((result) => {
        // here result will be [ 1 ], if the id column is unique in your table
        // the problem is that you can't return updated instance, you would have to retrieve it from database once again
        return result;
    }).catch(e => {
        console.log(e);
    });
};

Ou la deuxième option avec retour d'instance et mise à jour sur celle-ci

exports.updateItem = function(item) {
    return models.TimesheetItem.findById(item.id).then((itemInstance) => {
        return itemIstance.update(item).then((self) => {
            return self;
        });
    }).catch(e => {
        console.log(e);
    });
}

La différence est que vous n'avez pas besoin de créer et de renvoyer vos propres Promise - méthodes séquentielles comme update() renvoient des promesses par elles-mêmes.

16
piotrbienias