Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

142
Views
Tratando de crear una instancia y varias instancias relacionadas en una relación de muchos a muchos

Estoy intentando crear una instancia y varias instancias relacionadas con una relación de muchos a muchos usando una tabla de unión.

Al crear las múltiples instancias relacionadas, también necesito agregar un valor a una propiedad en la tabla de unión. No sé si es mi falta de conocimiento de secuelas o promesas lo que está causando mi problema.

El código que estoy usando está debajo. Este código agrega los elementos a la base de datos, pero necesito redirigir después de que se haya completado la operación, lo cual no funciona.

Básicamente, necesito crear una Receta. Una vez que se crea, necesito crear Ingredientes y relacionarlos con esa Receta. Los ingredientes se almacenan en una matriz procedente de un formulario en una página HTML. Al relacionar los ingredientes, necesito agregar la cantidad_ingrediente a la tabla Ingredientes de la receta, que es la parte intermedia de la relación (la tabla de unión).

 global.db.Recipe.belongsToMany( global.db.Ingredient, { as: 'Ingredients', through: global.db.RecipeIngredients, foreignKey: 'recipe_id' }); global.db.Ingredient.belongsToMany( global.db.Recipe, { as: 'Recipes', through: global.db.RecipeIngredients, foreignKey: 'ingredient_id' }); router.post('/new', ensureLoggedIn, bodyParser.json(), function (req, res) { var recipeName = req.body.recipe_name; var steps = req.body.steps; var ingredients = req.body.ingredients; var ingredientQty = {}; var currentIngredient; var ingredientsToAdd = []; db.Recipe.create({ recipe_name: recipeName, directions: steps, FamilyId: req.user.FamilyId, CreatedBy: req.user._id }) .then(function (recipe) { for (var i = 0; i < ingredients.length; i++) { currentIngredient = ingredients[i]; ingredientQty[currentIngredient.ingredient_name] = currentIngredient.quantity; db.Ingredient.findOrCreate({ where: { ingredient_name: currentIngredient.ingredient_name, FamilyId: req.user.FamilyId } }) .spread(function (ingredient, created) { if (created) { console.log("Added Ingredient to DB: " + currentIngredient.ingredient_name); } ingredient.Recipes = { ingredient_quantity: ingredientQty[ingredient.ingredient_name] }; ingredient.CreatedBy = req.user._id; recipe.addIngredient(ingredient) .then(function () { console.log("Added Ingredient " + ingredient.ingredient_name + " to Recipe " + recipe.recipe_name); }); }) } }) .finally(function(recipe){ res.redirect('/recipes'); }); });

Cualquier ayuda sería muy apreciada. Sé que tengo problemas al tratar de usar promesas dentro de un ciclo, pero no sé de qué otra manera puedo lograr esto.

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Con Sequelize, puede crear objetos junto con sus objetos asociados en un solo paso, siempre que todos los objetos que esté creando sean nuevos . Esto también se llama creación anidada. Vea este enlace y desplácese hacia abajo hasta la sección titulada "Crear con asociaciones"

En cuanto a su problema, tiene una relación de muchos a muchos entre Recipe e Ingredient , siendo RecipeIngredients la tabla de unión.

Supongamos que tiene un nuevo objeto Receta que desea crear, como:

 var myRecipe = { recipe_name: 'MyRecipe', directions: 'Easy peasy', FamilyId: 'someId', CreatedBy: 'someUserId' }

Y una matriz de objetos Ingrediente, como:

 var myRecipeIngredients = [ { ingredient_name: 'ABC', FamilyId: 'someId'}, { ingredient_name: 'DEF', FamilyId: 'someId'}, { ingredient_name: 'GHI', FamilyId: 'someId'}] // associate the 2 to create in 1 step myRecipe.Ingredients = myRecipeIngredients;

Ahora, puede crear myRecipe y sus myRecipeIngredients asociados en un solo paso, como se muestra a continuación:

 Recipe.create(myRecipe, {include: {model: Ingredient}}) .then(function(createdObjects){ res.json(createdObjects); }) .catch(function(err){ next(err); });

Y eso es todo !!
Sequelize creará 1 fila en Recipe , 3 filas en Ingredient y 3 filas en RecipeIngredients para asociarlos.

about 4 years ago · Santiago Trujillo Report

0

Pude solucionar el problema que estaba teniendo. Las respuestas aquí me ayudaron a encontrar mi solución. Estoy publicando la solución a continuación en caso de que alguien más tenga un problema similar. Creé una variable para almacenar la Promesa de Recipe.create(), usé Promise.map para encontrar o crear todos los ingredientes de los datos del formulario. Debido a que findOrCreate devuelve una matriz que contiene Promise y un valor booleano si se creó el elemento, tuve que obtener los ingredientes reales de los resultados de la función Promise.map. Así que utilicé la función JavaScript array.map() para obtener el primer elemento de las matrices. Y finalmente, use Promise.map nuevamente para agregar cada ingrediente a la receta.

 var ingredients = req.body.ingredients, recipeName = req.body.recipeName, ingredientsQty = {}; // Used to map the ingredient and quantity for the // relationship, because of the Junction Table var recipe = models.Recipe.create({recipe_name: recipeName}); // Use Promise.map to findOrCreate all ingredients from the form data Promise.map(ingredients, function(ing){ ingredientsQty[ing.ingredient_name] = ing.ingredient_quantity; return models.Ingredient.findOrCreate({ where: { ingredient_name: ing.ingredient_name}}); }) // Use JavaScript's Array.prototype.map function to return the ingredient // instance from the array returned by findOrCreate .then(function(results){ return results.map(function(result){ return result[0]; }); }) // Return the promises for the new Recipe and Ingredients .then(function(ingredientsInDB){ return Promise.all([recipe, ingredientsInDB]); }) // Now I can use Promise.map again to create the relationship between the / // Recipe and each Ingredient .spread(function(addedRecipe, ingredientsToAdd){ recipe = addedRecipe; return Promise.map(ingredientsToAdd, function(ingredientToAdd){ ingredientToAdd.RecipeIngredients = { ingredient_quantity: ingredientsQty[ingredientToAdd.ingredient_name] }; return recipe.addIngredient(ingredientToAdd); }); }) // And here, everything is finished .then(function(recipeWithIngredients){ res.end });
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!