es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cree un registro y conéctelo a un registro existente de cliente prisma (relación 1 a 1).

Estoy haciendo una aplicación de Next JS con Prisma y Postgres. Tengo 2 tablas: Usuario y Perfil. Su estructura de esquema Prisma es la siguiente:

modelo Usuario {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  // claves foráneas
  sessions      Session[]
  profile       Profile?
}

modelo Profile {
  id                Int      @id @default(autoincrement())
  isAdmin           Boolean  @default(false)
  firstName         String
  lastName          String
  email             String   @unique
  phone             String
  address           String
  gender            String
  image             Bytes
  guardianName1     String
  guardianPhone1    String
  guardianRelation1 String
  guardianName2     String?
  guardianPhone2    String?
  guardianRelation2 String?
  guardianName3     String?
  guardianPhone3    String?
  guardianRelation3 String?
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt
  // claves foráneas
  user              User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId            String   @default(cuid()) // campo escalar de relación (usado en el atributo <code>@relation</code> anterior)
  requests          Request[]
}

También estoy usando next-auth para la autenticación de esta aplicación. Así que cuando un usuario se registra, después de la verificación de su correo electrónico, next-auth agrega automáticamente el registro del usuario a la tabla Usuario. Hasta aquí, no hay problema.

Luego, cuando el usuario abre su panel por primera vez, se le muestra un formulario para completar. Al enviar ese formulario, se necesita insertar un registro en la tabla Perfil. Como las tablas Perfil y Usuario están relacionadas, también necesitan estar conectadas.

Así que cuando el usuario envía el formulario de detalles del perfil, hago lo siguiente:

try {
    const newProfileData = {
        // otros datos de los campos aquí...
        user: {
            connect: { id: '1' } // donde la tabla Usuario ya tiene un registro con - 'id': 1
        }
    };
    const profile = await prisma.profile.create({ data: newProfileData, include: { user: true } });
    if(profile) { 
        console.log("Creado: ", profile);
        res.status(200).json({ msg: 'Perfil creado correctamente!' }); 
    }
}
catch(err)
{
    console.log(err);
}

Pero al ejecutar este código, obtengo el error:

El cambio que estás intentando hacer violaría la relación requerida 'PerfilAUsuario' entre los modelos `Perfil` y `Usuario`.
...
codigo: &#39;P2014&#39;,
clientVersion: &#39;2.30.3&#39;,
meta: {
    relation_name: &#39;ProfileToUser&#39;,
    model_a_name: &#39;Profile&#39;,
    model_b_name: &#39;User&#39;
}

¿Cómo se puede solucionar esto? Incluso lo intenté de otra manera (es decir, actualizando el Usuario existente y creando el registro del Perfil conectado a él):

const user = await prisma.user.update({
    where: {
        email: req.body.email,
    },
    data: {
        profile: {
            create: {
                // datos de los campos aquí... (sin el campo user)
            },
        },
    },
});

Pero esto también da el mismo error… Quiero entender por qué viene el error. ¿No es esta la forma correcta de crear un registro para una relación 1 a 1 usando Prisma Client?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error sugiere que la relación entre los modelos Profile y User no se cumple al intentar crear un nuevo registro en la tabla Profile. Esto se debe a que cada registro de Profile debe estar vinculado a un registro correspondiente de User mediante el campo userId, que actúa como una clave externa.

    Para solucionar esto, debes asegurarte de que el campo userId en el objeto newProfileData esté configurado con el mismo valor id que el registro de User al que deseas vincularlo. En lugar de codificar el valor id como '1', puedes obtenerlo dinámicamente del objeto de usuario autenticado proporcionado por next-auth cuando el usuario inicia sesión.

    Suponiendo que hayas agregado un callback de sesión a next-auth para recuperar los datos del usuario de Prisma, puedes acceder al valor id del usuario actual utilizando session.user.id. Aquí hay un ejemplo de cómo puedes actualizar tu código para configurar dinámicamente el campo userId:

    const session = await getSession({ req });
    
    if (!session || !session.user) {
      // manejar usuario no autenticado
    }
    
    const userId = session.user.id;
    
    try {
      const newProfileData = {
        // otros datos de campos aquí...
        userId,
      };
    
      const profile = await prisma.profile.create({
        data: newProfileData,
        include: { user: true }
      });
    
      if (profile) { 
        console.log("Creado: ", profile);
        res.status(200).json({ msg: '¡Perfil creado con éxito!' }); 
      }
    }
    catch(err) {
      console.log(err);
    }
    

    Al configurar el campo userId con el valor id del usuario actualmente conectado, estás asegurando que los registros de Profile y User estén correctamente vinculados, y el mensaje de error ya no debería aparecer.

Comments are closed.