sql - TypeORM: @JoinTable con tres columnas
Tengo una pregunta sobre TypeORM y los decoradores @JoinTable y @RelationId. Tal vez alguien pueda ayudarme a responder mi pregunta, darme una pista o, idealmente, resolver mi problema.
Estoy usando NestJS con TypeORM para proporcionar una API privada con recetas para mi familia y para mí.
Si desgloso la estructura de la base de datos al mínimo, tenemos tres entidades principales:
recipe
- id INT(11)
- name VARCHAR(255)
PRIMARY KEY is id
ingredient
- id INT(11) // not autoincrement, fetched from https://www.programmableweb.com/api/chomp
- name VARCHAR(255)
- recipeId INT(11)
PRIMARY KEY is a composite key (id, recipeId)
FOREIGN KEY is recipeId on recipe
step
- id INT(11)
- name VARCHAR(255)
- recipeId INT(11)
PRIMARY KEY is id
FOREIGN KEY is recipeId on recipe
Entonces, estas son mis tres entidades principales para mis recetas. Una receta puede tener múltiples pasos (muchos-pasos-para-una-receta) y una receta puede tener múltiples ingredientes (muchos-ingredientes-para-una-receta)
Ahora la parte compleja. Cada paso puede tener una relación con uno o muchos ingredientes. Esto resulta en la siguiente tabla de relaciones.
ingredient_steps_step
- ingredientId INT(11)
- stepId INT(11)
- recipeId INT(11)
PRIMARY KEY is a composite key (ingredientId, stepId, recipeId)
FOREIGN KEYS are ingredientId on ingredient, stepId on step, recipeId on recipe
Mi ingredient.entity.ts se ve así:
@ManyToMany(type => Step, step => step.ingredients)
@JoinTable({
name: 'ingredient_steps_step',
joinColumns: [
{name: 'ingredientId'},
{name: 'recipeId'},
],
inverseJoinColumns: [
{name: 'stepId'},
],
})
steps: Step[];
@RelationId((ingredient: Ingredient) => ingredient.steps)
stepIds: number[];
@PrimaryColumn()
recipeId: number;
@PrimaryColumn()
id: number;
@ManyToOne(type => Recipe, recipe => recipe.ingredients)
recipe: Recipe;
El problema es que mi tabla de ingredientes se llena, pero la tabla de relación (ingredient_steps_step) no se llena con las entradas. El problema es que no existe un decorador como @RelationIds, donde pueda proporcionar dos columnas para la relación con la entidad step.
Sería genial si alguno de ustedes pudiera ayudarme con esto. ¿Tal vez sea necesario proporcionarles más información sobre las otras entidades?
Saludos cordiales,
digitalhacke
Respuesta #1
Cada relación debe estar en su propia tabla. Si representas dos relaciones en una tabla, crearás duplicación y podrías terminar con inconsistencias.
Ejemplo
Supongamos que tienes una receta MyRecipe con un paso Step1 que tiene dos ingredientes. Ahora quieres mover Step1 a otra receta OtherRecipe. Debido a que la relación MyRecipe <-> Step1 está representada dos veces (duplicación), tienes que cambiar múltiples entradas. Si olvidas una, terminarás con datos corruptos.
ingredient_steps_step:
MyRecipe <-> Step1 <-> IngredientA
MyRecipe <-> Step1 <-> IngredientB
Modelaría los datos de la siguiente manera:
steps:
Step1 -> MyRecipe
step_ingredients:
Step1 <-> IngredientA
Step1 <-> IngredientB
De esta manera, no hay duplicación. Supongo que los ingredientes de una receta son la unión de los ingredientes de todos sus pasos.
