5
votes

Comment renvoyer uniquement des attributs spécifiques lors de l'utilisation de la méthode Sequelize Create

J'ai cherché dans la documentation et les forums de Sequelize la syntaxe correcte et il semble que je le fasse de la bonne manière, mais pour une raison quelconque, le champ du mot de passe est toujours renvoyé dans la charge utile de la réponse ...

Le lien suivant montre que les attributs excluent la syntaxe que j'utilise ont été ajoutés dans la version 3.11 de Sequelize: https://github.com/sequelize/sequelize/issues/4074

Quelqu'un sait ce que je pourrais manquer ici? Vous trouverez ci-dessous la méthode Create et le journal de la console de l'instruction Insert .

Create méthode

async create(req, res) {
try {
    let user = await User.create({
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        email: req.body.email,
        password: req.body.password
    }, {
        attributes: {
            exclude: ['password']
        }
    });

    console.log("USER: ", user);

    res.status(201).send(user.toJSON());
}
catch (error) {
    res.status(500).send(error)
};

}

Journal de la console

Exécution (par défaut): INSERT INTO "Users" ("id", "firstName", "lastName", "email", "password", "createdAt", "updatedAt") VALUES (DEFAULT, 'James', 'Martineau' , 'test @ gmail.com', '2 milliards $ 10 $ 7ANyHzs74OXYfXHuhalQ3ewaS4DDem1cHMprKaIa7gO434rlVLKp2', '2019-02-28 15: 18: 15.856 +00: 00', '2019-02-28 15: 18: 15.856 +00: 00' ) RETOUR *;

USER: User {dataValues: {id: 6, firstName: 'James', lastName: 'Martineau', email: 'test@gmail.com', mot de passe: '2b $ 10 $ 7ANyHzs74OXYfXHuhalQ3ewaS4DDem1cHMprKaIa7gO434rlVLKT2 mis à jour: 2019-02-28 : 18: 15.856Z, crééAt: 2019-02-28T15: 18: 15.856Z} ...


1 commentaires

je suis toujours à la recherche de ce dont vous aviez besoin. Vous avez trouvé un moyen de le faire sans propriété. supprimer toutes mes propriétés ne semble pas être une solution sèche


5 Réponses :


1
votes

Avec une lecture rapide de la documentation, il semble que les attributes ne soient mentionnés que dans les requêtes telles que:

let user = await User.create({
    firstName: req.body.firstName,
    lastName: req.body.lastName,
    email: req.body.email,
    password: req.body.password
}, {
    fields: ['firstName', 'lastName', 'email']
});

( http://docs.sequelizejs.com/manual/tutorial/querying.html#attributes )

Si vous souhaitez exclure le password de password avec create , vous pouvez faire quelque chose comme:

Model.findAll({
  attributes: { exclude: ['baz'] }
});

( http://docs.sequelizejs.com/manual/tutorial/instances.html#creating-persistent-instances )


5 commentaires

Merci Scott, mais je ne pense pas que votre réponse soit correcte. La documentation semble indiquer que le paramètre fields dicte les champs qui seront définis. Cela a également du sens, car lorsque j'ai tenté de mettre en œuvre votre suggestion par Sequelize User, le modèle a explosé parce que le mot de passe n'a pas été fourni, seuls les 3 champs définis l'ont été.


Ah, j'ai peut-être mal compris votre intention. Avez-vous essayé: User.create({ //... {include: ['firstName', 'lastName', 'email']} }) ?


Le paramètre include est utilisé pour les associations de modèles. Comme il s'agit simplement d'une fonction de création et qu'aucune association n'est ajoutée ici, le paramètre include ne serait pas approprié. J'essaye essentiellement d'ajouter le paramètre d' attributes pour Sequelize.create mais apparemment il y a une manière différente de le faire ...?


Hmm ... la seule chose à laquelle je peux penser maintenant est de create abord, puis de rechercher le même enregistrement avec findOne et de le renvoyer. De cette façon, vous pouvez utiliser des attributes pour exclude password .


On dirait qu'il devrait également être possible d'utiliser findOrCreate ; par exemple, let [user] = await User.findOrCreate({ firstName: req.body.firstName, lastName: req.body.lastName, email: req.body.email, password: req.body.password }, { attributes: { exclude: ['password'] } }); Faites-moi savoir si cela fonctionne et je modifierai volontiers la réponse.



1
votes

Je vois dans le document que vous ne pouvez pas exclure des attributs lorsque vous créez un modèle. Exclure uniquement lorsque vous trouvez un modèle.

Je suggère:

async create(req, res) 
{
try {
    let user = await User.create({
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        email: req.body.email,
        password: req.body.password
    });
    delete user["password"];//delete field password
    console.log("USER: ", user);

    res.status(201).send(user.toJSON());
}
catch (error) {
    res.status(500).send(error)
};
}


1 commentaires

Voici le résultat final delete user.dataValues.password Interroger à nouveau la base de données pour obtenir les attributs spécifiques serait plus coûteux.



0
votes

 User.create(req.body).then(user => {
    delete user.dataValues.password
    res.json(user)
  }).catch(error => {
   // do something with error
  })


0 commentaires

1
votes

Essayez de surcharger la classe Sequelize Model avec la fonctionnalité souhaitée. Par exemple, exécutez le code suivant une fois pendant le démarrage de l'application:

import {Model} from 'sequelize';

const toJSON = Model.prototype.toJSON;

Model.prototype.toJSON = function ({attributes = []} = {}) {
    const obj = toJSON.call(this);

    if (!attributes.length) {
      return obj;
    }

    return attributes.reduce((result, attribute) => {
      result[attribute] = obj[attribute];

      return result;
    }, {});
  };

Après cela, vous pouvez utiliser votre code comme d'habitude, mais avec une option d' attributes :

User.toJSON({attributes: ['name', 'etc...']}) .


0 commentaires

0
votes

La bonne façon de gérer cela consiste à tirer parti des hooks afterCreate et afterUpdate sur le modèle de données réel, que Sequelize expose. Ces hooks sont déclenchés après la persistance de l'enregistrement, donc toutes les mutations des dataValues ne seront reflétées que dans le retour.

sequelize.define(
    'User',
    {
        id: { type: DataType.UUID, defaultValue: Sequelize.UUIDV4, primaryKey: true },
        username: { type: DataType.STRING, allowNull: false },
        password: { type: DataType.STRING, allowNull: false }
    },
    {
        hooks: {
            afterCreate: (record) => {
                delete record.dataValues.password;
            },
            afterUpdate: (record) => {
                delete record.dataValues.password;
            },
        }
    }
);

Voici un lien vers la documentation: https://sequelize.org/master/manual/hooks.html


0 commentaires