Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 09ad83a

Browse files
committed
Se finalizó la relacion muchos a muchos de ordenes - productos
1 parent e7770c6 commit 09ad83a

File tree

8 files changed

+212
-12
lines changed

8 files changed

+212
-12
lines changed

PasoAPaso.txt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,27 @@
166166
- Modificar los metodos del servicio de category para incluir asociación en el archivo: services/categories/category.service.js
167167
- Modificar los metodos del servicio de product para incluir asociación en el archivo: services/products/product.service.js
168168

169-
30. Relaciones muchos a muchos (Product <-----> Orders). Necesitamos una tabla intermedia (Orden de Compra):
170-
- Realizar la relación en el archivo: models/order.model.js
171-
- Realizar la relación en el archivo: models/customer.model.js
172-
- Ejecutar las relaciones en el archivo: models/index.js
173-
- Ejecutar en consola el script: npm run migrations:generate order
174-
- Modificar los metodos del servicio de order para incluir asociación en el archivo: services/orders/order.service.js
169+
30. Relaciones uno a muchos (Customer -----> Order): - Realizar la relación en el archivo: models/order.model.js
170+
- Realizar la relación en el archivo: models/customer.model.js
171+
- Ejecutar las relaciones en el archivo: models/index.js
172+
- Ejecutar en consola el script: npm run migrations:generate order
173+
- Ejecutar en consola el comando: npm run migrations:run
174+
- Modificar los metodos del servicio de order para incluir asociación en el archivo: services/orders/order.service.js
175+
176+
31. Relaciones muchos a muchos (Product <-----> Order). Necesitamos una tabla intermedia (Order-Product):
177+
- Realizar la relación en el archivo: models/order-product.model.js
178+
- Realizar la relación en el archivo: models/order.model.js
179+
- Ejecutar las relaciones en el archivo: models/index.js
180+
- Ejecutar en consola el script: npm run migrations:generate order-product
181+
- Ejecutar en consola el comando: npm run migrations:run
182+
- Modificar los metodos del servicio de order para incluir asociación en el archivo: services/orders/order.service.js
183+
184+
185+
175186

176187
• Consultas •
177188

178-
30.
189+
32.
179190

180191

181192

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
// Importando el modelo Order Product
4+
const {
5+
OrderProductSchema,
6+
ORDER_PRODUCT_TABLE,
7+
} = require('./../models/order-product.model');
8+
9+
module.exports = {
10+
async up(queryInterface) {
11+
/**
12+
* Add altering commands here.
13+
*
14+
* Example:
15+
* await queryInterface.createTable('users', { id: Sequelize.INTEGER });
16+
*/
17+
// Creando tabla, indicamos el nombre de la tabla y el esquema
18+
await queryInterface.createTable(ORDER_PRODUCT_TABLE, OrderProductSchema);
19+
},
20+
21+
async down(queryInterface) {
22+
/**
23+
* Add reverting commands here.
24+
*
25+
* Example:
26+
* await queryInterface.dropTable('users');
27+
*/
28+
// Eliminando tabla
29+
await queryInterface.dropTable(ORDER_PRODUCT_TABLE);
30+
},
31+
};

db/models/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const { Category, CategorySchema } = require('./category.model');
1010
const { Product, ProductSchema } = require('./product.model');
1111
// Importando modelo order
1212
const { Order, OrderSchema } = require('./order.model');
13+
// Importando modelo order product
14+
const { OrderProduct, OrderProductSchema } = require('./order-product.model');
1315

1416
// Configuración de los modelos
1517
function setupModels(sequelize) {
@@ -23,13 +25,16 @@ function setupModels(sequelize) {
2325
Product.init(ProductSchema, Product.config(sequelize));
2426
// Le indicamos al modelo order que debe seguir el esquema de OrderSchema
2527
Order.init(OrderSchema, Order.config(sequelize));
28+
// Le indicamos al modelo order product que debe seguir el esquema de OrderProductSchema
29+
OrderProduct.init(OrderProductSchema, OrderProduct.config(sequelize));
2630

2731
// Ejecución del método associate (Enviamos los modelos)
2832
User.associate(sequelize.models);
2933
Customer.associate(sequelize.models);
3034
Category.associate(sequelize.models);
3135
Product.associate(sequelize.models);
3236
Order.associate(sequelize.models);
37+
OrderProduct.associate(sequelize.models);
3338
}
3439

3540
// Exportamos módulo

db/models/order-product.model.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Importando Sequelize y elementos necesarios
2+
const { Model, DataTypes, Sequelize } = require('sequelize');
3+
4+
// Importando nombre de la tabla (Entidad) Users
5+
const { ORDER_TABLE } = require('./order.model');
6+
// Importando nombre de la tabla (Entidad) Products
7+
const { PRODUCT_TABLE } = require('./product.model');
8+
9+
// Definimos nombre de la tablaa (Entidad)
10+
const ORDER_PRODUCT_TABLE = 'orders_products';
11+
12+
// Definimos el esquema de la entidad
13+
const OrderProductSchema = {
14+
id: {
15+
allowNull: false,
16+
autoIncrement: true,
17+
primaryKey: true,
18+
type: DataTypes.INTEGER,
19+
},
20+
createdAt: {
21+
allowNull: false,
22+
type: DataTypes.DATE,
23+
// Nombre con el que se guardara el atributo en la BD (_) por buenas prácticas
24+
field: 'created_at',
25+
defaultValue: Sequelize.NOW,
26+
},
27+
amount: {
28+
allowNull: false,
29+
type: DataTypes.INTEGER,
30+
},
31+
// Atriburo para relacionar con la tabla order
32+
orderId: {
33+
// Nombre con el que se guardara el atributo en la BD (_) por buenas prácticas
34+
field: 'order_id',
35+
allowNull: false,
36+
type: DataTypes.INTEGER,
37+
// Indicamos la tabla a la que va relacionada
38+
references: {
39+
model: ORDER_TABLE,
40+
// Foreign Key
41+
key: 'id',
42+
},
43+
onUpdate: 'CASCADE',
44+
onDelete: 'CASCADE',
45+
},
46+
// Atriburo para relacionar con la tabla product
47+
productId: {
48+
// Nombre con el que se guardara el atributo en la BD (_) por buenas prácticas
49+
field: 'product_id',
50+
allowNull: false,
51+
type: DataTypes.INTEGER,
52+
// Indicamos la tabla a la que va relacionada
53+
references: {
54+
model: PRODUCT_TABLE,
55+
// Foreign Key
56+
key: 'id',
57+
},
58+
onUpdate: 'CASCADE',
59+
onDelete: 'CASCADE',
60+
},
61+
};
62+
63+
// Definimos una clase para nuestra entidad
64+
class OrderProduct extends Model {
65+
// Método static es un método que pertenece a la clase y no al objeto
66+
67+
// Función para realizar las relaciones
68+
static associate() {}
69+
70+
// Función para realizar la configuración (Recibimos una conexión)
71+
static config(sequelize) {
72+
return {
73+
// Conexión que tendra
74+
sequelize,
75+
// Nombre de la tabla
76+
tableName: ORDER_PRODUCT_TABLE,
77+
// Nombre del modelo (Clase)
78+
modelName: 'OrderProduct',
79+
timestamps: false,
80+
};
81+
}
82+
}
83+
84+
// Exportamos módulos
85+
module.exports = {
86+
ORDER_PRODUCT_TABLE,
87+
OrderProductSchema,
88+
OrderProduct,
89+
};

db/models/order.model.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ const OrderSchema = {
3838
onUpdate: 'CASCADE',
3939
onDelete: 'CASCADE',
4040
},
41+
// Calcular el total
42+
total: {
43+
// Campo virtual, que no estará en la BD
44+
type: DataTypes.VIRTUAL,
45+
get() {
46+
// Validando si hay elementos (items, es la manera en la que llamamos la asociación VER LINEA 64)
47+
if (this.items.length > 0) {
48+
return this.items.reduce((total, item) => {
49+
return total + item.price * item.OrderProduct.amount;
50+
}, 0);
51+
}
52+
return 0;
53+
},
54+
},
4155
};
4256

4357
// Definimos una clase para nuestra entidad
@@ -46,8 +60,18 @@ class Order extends Model {
4660

4761
// Función para realizar las relaciones
4862
static associate(models) {
49-
// Relación uno a muchos (Order ----> Customer) Foreign Key se define en la tabla Order
63+
// Relación uno a uno (Order ----- Customer) Foreign Key se define en la tabla Order
5064
Order.belongsTo(models.Customer, { as: 'customer' });
65+
// Relación muchos a muchos (Order <----> Product) Foreign Key se define en la tabla OrderProduct, debemos enviar tabla intermedia
66+
Order.belongsToMany(models.Product, {
67+
as: 'items',
68+
// Nombre de la tabla intermedia que resolvera la relación
69+
through: models.OrderProduct,
70+
// Foreign Key definida en OrderProduct
71+
foreignKey: 'orderId',
72+
// Indicamos la otra Key definida en OrderProduct
73+
otherKey: 'productId',
74+
});
5175
}
5276

5377
// Función para realizar la configuración (Recibimos una conexión)

routes/orders/orders.router.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const OrderService = require('../../services/order/order.service');
77
const {
88
createOrderSchema,
99
getOrderSchema,
10+
addItemSchema,
1011
} = require('../../schemas/orders/order.schema');
1112
// Importando middleware de validaciones
1213
const validatorHandler = require('../../middlewares/validator.handler');
@@ -69,6 +70,25 @@ router.post(
6970
}
7071
);
7172

73+
// POST: Crear un producto en una orden (Antes de hacer la petición, validamos que el esquema sea correcto)
74+
router.post(
75+
'/add-item',
76+
validatorHandler(addItemSchema, 'body'),
77+
async(req, res, next) => {
78+
try {
79+
// Accediendo a los datos que vienen por el body (Utilizar postman o insomnia)
80+
const body = req.body;
81+
82+
// Creando una item ejecutando el método create
83+
const newItem = await service.addItem(body);
84+
res.status(201).json(newItem);
85+
} catch (error) {
86+
// Next permite ejecutar el siguiente middleware, en este caso los middleware tipo error que hayan
87+
next(error);
88+
}
89+
}
90+
);
91+
7292
// PATCH: Actualizar una orden (Antes de hacer la petición, validamos que el esquema sea correcto)
7393
router.patch(
7494
'/:id',

schemas/orders/order.schema.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const Joi = require('joi');
44
// Campos y sus validaciones
55
const id = Joi.number().integer();
66
const customerId = Joi.number().integer();
7+
const orderId = Joi.number().integer();
8+
const productId = Joi.number().integer();
9+
const amount = Joi.number().integer().min(1);
710

811
// Esquema de orden para obtener orden
912
const getOrderSchema = Joi.object({
@@ -15,5 +18,12 @@ const createOrderSchema = Joi.object({
1518
customerId: customerId.required(),
1619
});
1720

21+
// Esquema de item para la creación
22+
const addItemSchema = Joi.object({
23+
orderId: orderId.required(),
24+
productId: productId.required(),
25+
amount: amount.required(),
26+
});
27+
1828
// Exportamos módulo
19-
module.exports = { getOrderSchema, createOrderSchema };
29+
module.exports = { getOrderSchema, createOrderSchema, addItemSchema };

services/order/order.service.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ class OrderService {
1515
return newOrder;
1616
}
1717

18+
// Crear item
19+
async addItem(data) {
20+
// Creando item con las funcionalidades que nos brinda el ORM Sequelize
21+
const newItem = await models.OrderProduct.create(data);
22+
return newItem;
23+
}
24+
1825
// Buscar Ordenes
1926
async find() {
2027
return [];
@@ -27,9 +34,12 @@ class OrderService {
2734
// Incluimos las asociaciones definidas en la clase Order del modelo
2835
// (En este caso la anidación va mas a profundiad, es decir, aparte de customer también nos traerá la info del user)
2936
include: [{
30-
association: 'customer',
31-
include: ['user'],
32-
}, ],
37+
association: 'customer',
38+
include: ['user'],
39+
},
40+
// Incluimos asosiación items
41+
'items',
42+
],
3343
});
3444

3545
// Validando que la orden exista

0 commit comments

Comments
 (0)