web-dev-qa-db-fra.com

Sequelize hasMany Rejoignez l'association

Je développe mon application et je dois rejoindre deux modèles que j'avais créés précédemment avec Sequelize, ils sont les suivants:

Repas

sequelize.define('meal', {
    mealId: {
        type: DataTypes.INTEGER, 
        primaryKey: true,
        autoIncrement: true
    },
    quantity: {
        type: DataTypes.DECIMAL,
        allowNull: false
    },
    period: {
        type: DataTypes.INTEGER,
        allowNull: false
    }
})

Nourriture

sequelize.define('food', {
    idFood: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    nameFood: {
        type: DataTypes.STRING,
        allowNull: false
    }
})

J'ai ajouté la relation suivante:

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

Cette ligne ajoute une colonne idFood sur le repas

Expliquant rapidement ce qui se passe, La nourriture est une table avec de nombreux aliments (duh) comme le pain, le riz, les haricots, etc. Repas est un tableau qui identifie quel aliment l'utilisateur a choisi avec ses détails.

Par conséquent, ma compréhension était que Repas avait beaucoup Nourriture (comme je l'ai ajouté auparavant) mais La nourriture ne nécessitait aucune relation avec le repas , car il ne contient que des données et n'est pas modifié après que je l'ai rempli pour la première fois. Mais quand j'ai essayé de les rejoindre avec:

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals));
});

J'ai eu l'erreur suivante:

Unhandled rejection Error: food is not associated to meal!

Quelqu'un peut-il expliquer ce que je dois faire? Je pense que cela a à voir avec les relations, mais je n'ai pas pu trouver dans la documentation une bonne explication sur ce que je dois faire.

Je vous remercie!

Edit: En lisant la documentation ( again ), l'exemple est logique, mais je ne pense pas que l'exemple s'applique à ma situation, car sur leur exemple, l'utilisateur a une tâche et la tâche appartient à l'utilisateur . Mais dans mon cas, la nourriture n'appartient pas à un repas, car de nombreux repas peuvent avoir le même aliment en différentes quantités (ou pour différents utilisateurs).

12
leofontes

Le problème est que la relation doit être définie dans les deux sens. Actuellement, Sequelize sait comment obtenir de la nourriture -> repas en raison de

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

mais il ne sait pas comment se rendre à partir de repas -> nourriture. C'est pourquoi vous devez définir la même relation dans l'autre sens, comme ceci:

db.meal.belongsTo(db.food, {foreignKey : 'idFood'});

Cela n'ajoute aucune clé new car cela définirait meal.idFood que vous avez déjà défini avec votre première instruction.

Vous devriez maintenant pouvoir exécuter

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals)); <-- each array element of meals should have an attribute `food`
});
16
Steffen Langer

Si vous utilisez un alias sur l'association ({ as: 'Food' }), vous devez également l'utiliser sur l'instruction include.

Ce serait donc comme ça:

db.meal.findAll({ 
  include : [{
    model: db.food,
    as: 'Food'
  }]
}).then(function (meals) {
  console.log(JSON.stringify(meals));
});

Si une association est aliasée (en utilisant l'option as), vous devez spécifier cet alias lors de l'inclusion du modèle. Remarquez comment les outils de l'utilisateur sont aliasés comme des instruments ci-dessus. Pour obtenir ce droit, vous devez spécifier le modèle que vous souhaitez charger, ainsi que l'alias

Plus d'informations ici .

1
oleh.meleshko