web-dev-qa-db-fra.com

Ajouter une propriété à un objet renvoyé par Sequelize FindOne

J'essaie d'ajouter une propriété à une instance séquentielle avant de la renvoyer au client. 

router.get('/cats/1', function (req, res) {
    Cat.findOne({where: {id: 1}})
        .then(function (cat) {
            // cat exists and looks like {id: 1}
            cat.name = "Lincoln";
            // console.log of cat is {id: 1, name: Lincoln}
            res.json(cat);
        });
});

Le client ne voit que {id: 1} et pas la clé nouvellement ajoutée. 

  • Qu'est-ce qui se passe ici? 
  • Quel type d'objet est renvoyé par Sequelize? 
  • Comment puis-je ajouter de nouvelles propriétés à mes chats et les renvoyer? 
15
Rastalamm

La classe Sequelize Model (dont vos chats sont des instances) a une méthode toJSON() qui sera probablement utilisée par res.json pour sérialiser vos chats. La méthode renvoie le résultat de Model#get() ( https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L3613 ), qui utilise uniquement les attributs définis sur le modèle. Si vous voulez pouvoir définir le nom du chat, mais pas les noms de magasin dans la base de données, vous pouvez utiliser une colonne virtuelle pour définir votre modèle de chat:

sequelize.define('Cat', {
  // [other columns here...]
  name: Sequelize.VIRTUAL
});

Si vous ne souhaitez pas ajouter de propriétés à la définition du modèle, vous pouvez également:

cat = cat.toJSON(); // actually returns a plain object, not a JSON string
cat.name = 'Macavity';
res.json(cat);
25

Ce qui suit fonctionne pour sequelize v4.

...
const order = Order.findOne(criteria);
order.setDataValue('additionalProperty', 'some value');
...

J'espère que cela t'aides. C'est un peu tard, mais au cas où les gens cherchent toujours des réponses.

3
Eric Xin Zhang

Cela ne me permet pas de commenter la bonne réponse ci-dessus ( https://stackoverflow.com/a/38469390/562683 ), je voulais simplement ajouter un cas d'utilisation où cela m'a aidé. 

J'ai une base de données mysql existante dont nous ne pouvons pas modifier le schéma (elle doit fonctionner avec l'ancien système et le nouveau système jusqu'à ce que l'ancien système soit obsolète), mais nous avons également superposé MonogoDB pour des fonctionnalités supplémentaires jusqu'à ce que nous puissions créer un système. refactor.

La réponse ci-dessus de la propriété Virtual m'a aidé, car je faisais en principe un espace réservé pour les informations de la base de données mongo (dans ce cas, un journal d'activité des objets) et l'ajoutais à l'appel de service 'findMyObject'.

Par exemple: 

const model = sequelize.define('myobj', {
  id: {
    type: Sequelize.INTEGER,
    autoIncrement: true,
    primaryKey: true,
    field: 'eventId',
  },
  name: { type: Sequelize.STRING, allowNull: false },
  history: Sequelize.VIRTUAL,
  ...
}

Ensuite, dans MyObjectService, appel findMyObject: 

...
const result = yield MyObject.findOne(query);
result.history = yield getMyObjectHistoryArray(id);
return result;

Et le JSON résultant ressemble à: 

{
  "id": 1,
  "name": "My Name",
  "history": [ 
    {...},
    {...},
  ]
}

Nous avons donc été en mesure d'étendre l'objet sans changer la base de données, mais nous avons toujours un objet dans le backend où vous pouvez aller: 

let obj = yield findMyObject(id);
obj.name = "New Name";
return yield obj.save();  

Ce que vous ne pourriez pas faire si, dans la fonction findMyObject, vous avez soit {raw: true}, soit result.get({plain: true})

0
James Cori