Mongoose: FindOne renvoie la valeur par défaut du champ inexistant.

Créé le 23 juil. 2016  ·  3Commentaires  ·  Source: Automattic/mongoose

_Premièrement : une solution de contournement pour résoudre ce problème :_
Model.findOne({id: 'blabla'}).select('email password createdAt').lean().exec()

problème:

J'utilise un champ createdAt - qui a une valeur expire (TTL 24h ) et une valeur par défaut ( Date.now ) - dans mon modèle Users pour stocker la création informations de date des nouveaux utilisateurs créés.

Si l'utilisateur active le compte, le système supprime le champ createdAt .
Si l'utilisateur n'active pas le compte, le système supprime le compte de la collection Users après 24 heures.

Dans mes opérations d'authentification, je vérifie d'abord l'existant du champ createdAt .
Si l'utilisateur n'est pas activé, j'affiche un message comme Account is not activated.

Lorsque j'essaie la méthode FindOne aux fins de la procédure d'authentification ci-dessus, j'obtiens une Date.now bien qu'il n'y ait pas createdAt champ

Champ createdAt dans mon modèle User :
createdAt: { type: Date, expires: '24h', default: Date.now },

Ma méthode :
Users.findOne({email: username}, 'email, password, createdAt', function(err, user) {

En utilisant la méthode ci-dessus, la createdAt revient à chaque fois.

ps: j'ai cherché le problème mais je n'ai rien pu.

Commentaire le plus utile

Tombé sur le même problème.
@ vkarpov15 cela ne devrait pas fonctionner de cette façon. Bien que la valeur par défaut soit définie lors de l'enregistrement, il est trompeur de la définir lorsque le document find , car il devrait en fait renvoyer les données exactes stockées dans la base de données, n'est-ce pas ? Je voterais pour rouvrir le sujet.

Tous les 3 commentaires

C'est ainsi que fonctionnent les valeurs par défaut, lorsqu'il n'y a pas createdAt champ createdAt lors de la création d'un nouveau document :

schema.pre('save', function(next) {
  if (this.isNew) {
    this.createdAt = Date.now();
  }
  next();
});

De plus, je ne recommanderais pas de séparer les champs de votre projection Users.findOne({email: username}, 'email, password, createdAt' /** <-- remove commas here */) par des virgules.

Tombé sur le même problème.
@ vkarpov15 cela ne devrait pas fonctionner de cette façon. Bien que la valeur par défaut soit définie lors de l'enregistrement, il est trompeur de la définir lorsque le document find , car il devrait en fait renvoyer les données exactes stockées dans la base de données, n'est-ce pas ? Je voterais pour rouvrir le sujet.

Pas nécessairement, mangouste a beaucoup d'endroits où le document ne représente pas les données exactes stockées dans la base de données : getters, virtuals, etc. De toute façon, nous affirmons sur ce comportement et le changer casserait beaucoup de code de gens, donc nous ne le changerons pas à moins qu'il y ait beaucoup de demande pour le changer. Voici une solution de contournement :

createdAt: {
  type: Date,
  default: function() {
    if (this.isNew) { return new Date(); }
    return undefined;
  }
}

Cela fera en sorte que createdAt ne soit défini que lors de l'enregistrement dans la base de données, mais ce sera undefined si vous avez chargé un document à partir de la base de données et que createdAt ne l'est pas ensemble.

Cette page vous a été utile?
0 / 5 - 0 notes