Parece que no he entendido bien las asociaciones Sequelize .hasMany() y .belongsTo() y cómo usarlas en el servicio. Tengo dos modelos:
const User = db.sequelize.define("user", { uid: { /*...*/ }, createdQuestions: { type: db.DataTypes.ARRAY(db.DataTypes.UUID), unique: true, allowNull: true, }, }); const Question = db.sequelize.define("question", { qid: { /*...*/ }, uid: { type: db.DataTypes.TEXT, }, });Dado que un usuario puede tener muchas preguntas y cada pregunta pertenece a un solo usuario, tengo las siguientes asociaciones:
User.hasMany(Question, { sourceKey: "createdQuestions", foreignKey: "uid", constraints: false, }); Question.belongsTo(User, { foreignKey: "uid", targetKey: "createdQuestions", constraints: false, }); Lo que quiero lograr es esto: después de la creación de un objeto de pregunta, el qid debe residir en el objeto de usuario en "createdQuestions" , al igual que el uid reside en el objeto de pregunta en uid . Lo que pensé que las asociaciones de secuelas harían por mí es guardar llamadas individuales y actualizar el objeto de usuario. ¿Hay un método correspondiente? Lo que tengo hasta ahora es:
const create_question = async (question_data) => { const question = { /*... question body containing uid and so forth*/ }; return new Promise((resolve, rejected) => { Question.sync({ alter: true }).then( async () => await db.sequelize .transaction(async (t) => { const created_question = await Question.create(question, { transaction: t, }); }) .then(() => resolve()) .catch((e) => rejected(e)) ); }); };Sin embargo, esto solo crea un objeto de pregunta pero no actualiza al usuario. ¿Que me estoy perdiendo aqui?
En SQL, a diferencia de NoSQL, cada atributo tiene un tipo de datos fijo con un límite fijo de bits. Eso se manifiesta mediante el comando SQL al crear una nueva tabla:
CREATE TABLE teachers ( name VARCHAR(32), department VARCHAR(64), age INTEGER );La razón detrás de esto es permitirnos acceder fácilmente a cualquier atributo de la base de datos conociendo la longitud de cada fila. En nuestro caso, cada fila necesitará el espacio necesario para almacenar:
32 bytes (nombre) + 64 bytes (departamento) + 4 bytes (edad) = 100 byes
Esta es una característica muy poderosa en las bases de datos de relaciones , ya que minimiza el tiempo necesario para recuperar datos a tiempo constante, ya que sabíamos dónde se encuentra cada dato en la memoria.
Ahora, consideremos que tenemos estas 3 tablas
Digamos que queremos crear una relación de uno a muchos entre las clases y los maestros donde un maestro puede dar muchas clases.
Podemos pensarlo de esta manera. Pero, este modelo no es posible por 2 razones principales:
Otra forma sería esta:
Si bien este enfoque solucionará el problema del tamaño de columna limitado, ya no tenemos una única fuente de verdad . Los mismos datos se duplican y almacenan varias veces.
Es por eso que para esta relación de uno a muchos, necesitaremos almacenar la identificación del maestro dentro de esta tabla de clase.
De esta forma, todavía podemos encontrar todas las clases que un profesor puede impartir ejecutando
SELECT * FROM classes WHERE teacherID = teacher_idY evitaremos todos los problemas discutidos anteriormente.
Su relación es una relación de uno a muchos. Un usuario puede tener varias preguntas. En SQL, este tipo de relación se modela agregando un atributo a Pregunta llamado ID de usuario o UID como lo hizo. En Sequelize, esto se lograría a través de hasMany o BelongsTo así:
User.hasMany(Question) Question.belongsTo(User, { foreignKey: 'userId', constraints: false }) En otras palabras, no creo que necesite el atributo CreatedQuestions en Usuario. Solo se necesita una clave externa para modelar la relación oneToMany.
Ahora, al crear una nueva pregunta, solo necesita agregar el ID de usuario de esta manera
createNewQuestion = async (userId, title, body) => { const question = await Question.create({ userId: userId, // or just userId title: title, // or just title body: body // or just body }) return question }Recuerde, no almacenamos arreglos en SQL . Incluso si podemos encontrar una manera de hacerlo, no es lo que necesitamos. Siempre debe haber una mejor manera.