Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

CakePHP - Cannot add or update a child row: a foreign key constraint fails

Estas en el tema de CakePHP - Cannot add or update a child row: a foreign key constraint fails en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola, yo se q abundan estos temas sobre este error, pero ya no se q hacer. Quiero relacionar Usuario con Perfil. Un Usuario tiene un ...
  #1 (permalink)  
Antiguo 17/12/2013, 08:30
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
CakePHP - Cannot add or update a child row: a foreign key constraint fails

Hola,

yo se q abundan estos temas sobre este error, pero ya no se q hacer.

Quiero relacionar Usuario con Perfil.

Un Usuario tiene un solo Perfil - Un Perfil pertenece a un solo Usuario

La relacion es hasOne.

Tabla users: (solo pongo los campos relacionados)
id int(10)
post_id int(10)

Tabla posts
id int(10)
user_id int(10)

Tabla profiles
id int(10)
user_id int(10)


Nombro la tabla posts porq tambien tengo el campo user_id, eso tendra algo q ver?

Volviendo al tema de Usuario -> Perfil:
en el phpmyadmin relacione el campo user_id de la tabla "profiles" con el campo id de la tabla "users"

En ON DELETE y ON UPDATE no puse nada.

Tambien vacie todas las tablas y sigue igual.

...y eso es todo lo q hice

Alguna ayuda?

Gracias
  #2 (permalink)  
Antiguo 17/12/2013, 09:01
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
Tabla users: (solo pongo los campos relacionados)
id int(10)
post_id int(10)

Tabla posts
id int(10)
user_id int(10)

Tabla profiles
id int(10)
user_id int(10)
Perdona que te lo diga así, pero esto es un espanto...
Está tan mal armada que jamás te funcionará. Mi mejor consejo es que antes de proseguir, estudies un poco de fundamentos de base de datos y en especial lo que se denominan dependencias funcionales.

Para hacértelo simple, el tema, por o que parecen indicar tus tablas es que USERS tiene la FK de POSTS, y POSTS la FK de USERS...
Eso es lo que se denomina "dependencia circular" y es uno de los peores casos que puede existir en una base, por cuanto si para insertar un usuario necesitas la FK del post, y para poner un post, debe existir el usuario... la gallina nunca pondrá el huevo.
Los posts pertenecen a un usuario, y eso implica que cada post debe tener su correspondiente FK del usuario a quien pertenecen. Pero no se debe jamás poner la FK del post en la tabla de usuarios porque no es relevante, es redundante (por reflexibilidad es innecesario), y genera una dependencia imposible de cumplir.
Por otro lado, tampoco es posible poner en la tabla de perfiles a usuario, porque si un usuario tiene un perfil, es el usuario el que tiene la FK, y no el perfil.
Y si un usuario puede tener N perfiles, se requiere una tabla adicional (tabla relacional) para representar una relación N:N. Y eso significa que deberían existir la tabla USERS, la tabla PROFILES y una que podrías llamar USER_PROFILES, cuya PK está constituida por las FK de cada una de las otras dos tablas... al mismo tiempo.


¿Se va entendiendo?

Este es un tema ajeno al CakePHP, es un problema de bases de datos y te recomiendo que lo postees allá, o bien que pidas que lo muevan, para poder tratarlo en profundidad (los temas de BBDD no son de programación y viceversa).
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 17/12/2013, 09:23
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Hola.

Eso de post_id fue un error. Eso va en la tabla de comentarios.

El error estaba en q queria insertar un valor nulo en user_id (q ya lo cambie por id_user para q no quede igual q en la tabla posts).

No estaba tomando el id del user entonces el campo estaba vacio y me generaba ese error.

Por lo demas, estoy siguiendo las convenciones de cakephp.

Los campos relacionados tienen el mismo tipo de dato y son unicos.

Bien decis al final, el usuario tiene q tener la FK y no el perfil... Ahi es cuando me trabo, cuando la relacion es uno a uno no se cual toma como FK, si el campo de uno o el campo del otro.

Tambien estoy leyendo sobre integridad referencial.

Gracias
  #4 (permalink)  
Antiguo 17/12/2013, 09:44
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
Bien decis al final, el usuario tiene q tener la FK y no el perfil... Ahi es cuando me trabo, cuando la relacion es uno a uno no se cual toma como FK, si el campo de uno o el campo del otro.
Por eso te digo que tu problema no es con CakePHP, es con Bases de Datos.
Saber programar no significa que sepas diseñar bases de datos. Son sistemas de razonamiento y lógica totalmente diferentes (eso decían mis profesores, y mi experiencia les ha dado la razón).

Es difícil de entender cuando te inicias, pero mirar las cosas como diseñador de DATOS no es lo mismo que mirarlo como PROGRAMADOR. No se ven las cosas de la misma forma.

Sería mejor que te concentraras en la aplicación en CakePHP, pero preguntes los temas más profundos de BBDD en el foro de BBDD. Así no confundimos ni mezclamos las cosas.

PD: "Integridad referencial" es una propiedad esperable del modelo relacional. Pero no ES el modelo relacional. El problema que tienes no es exactamente de integridad sino de dependencia funcional, que es otra parte del modelo.
El inconveniente se suscita porque una FK es una restricción puesta en la base, tal que no puede insertarse un valor en un campo X de una tabla A, si no existe previamente como PK de la tabla B, a la que hace referencia.
En tu caso, si creas una relación circular (A depende de B y B depende de A), nunca podrás meter los registros porque no se meten al mismo tiempo en ambas tablas, ni siquiera en el más poderoso servidor de BBDD. Siempre entran en forma secuencial, y por ende si metes en A, no existe aun eb B y falla. Pero si lo metes en B, como en A no existe, también falla.
¿Se entiende la idea?
Bueno, eso es lo que se denomina "dependencia circular" y es un fallo gravísimo en un modelo de bases de datos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 17/12/2013, 09:54
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Aca es donde esta el dilema de mi pregunta:

Cita:
Una clave foránea es simplemente un campo en una tabla que se corresponde con la clave primaria de otra tabla. Para este ejemplo, el campo id_cliente en la tabla venta es la clave foránea. Nótese que este campo se corresponde con el campo id_cliente en la tabla cliente, en dónde este campo es la clave primaria.
Las claves foráneas tienen que ver precisamente con la integridad referencial, lo que significa que si una clave foránea contiene un valor, ese valor se refiere a un registro existente en la tabla relacionada.
ftp://200.105.165.248/curso_android/...en%20MySQL.pdf


Es lo q yo hice.
El campo id de la tabla "users" es llave primaria, el campo user_id de la tabla "profiles" es la FK q se relaciona con la llave primaria de "users".

Lo logico es q si tengo muchas tablas q se relacionan con una sola, esa sola va a tener su llave primaria y las demas van a tener sus campos FK para q se relacionen. Es como yo lo entiendo en un caso simple como este...

pd: ya algun mod movera el post a otro foro, no se como avisarles
  #6 (permalink)  
Antiguo 17/12/2013, 10:12
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Bueno, or lo pronto estás tratando de aprender a relacionar tablas, basandote en un manual de MySQL donde el autor sescribe para quienes ya entienden y manejan los fundamentos del modelo Entodad-Relación y saben cómo diseñar una base de datos relacional...

El asunto se te va a complicar porque hay muchos conceptos que evidentemente no conoces.
Por lo pronto, antes de llegar a establecer qué tabla lleva la FK, debes entender cómo es la relación entre las entidades de tu sistema.
Resumiendo, tienes:
1) Usuarios.
2) Perfiles.
3) Posts.
Ero estos tres elementos sólo nos dice eso: Que hay usuarios, perfiles y posts, pero no explican las relaciones entre ellos.
Esas relaciónes se ven cuando expresas el comportamiento y las vinculaciones con las reglas del negocio:
- "Un usuario debe tener un perfil".
- "Un mismo perfil es aplicable a uno o más usuarios".
- "Un usuario puede tener cero o N posts".
- "Cada post sólopuede pertenecer a un único usuario".
- "Cada post tiene un tema inicial".
- "Cada tema iniciado tiene un posts asociado."

Esto es un ejemplo.
En este punto se puede ver que cada una de las tablas se puede relacionar en un vinculo de uno a uno (1:1), de uno a muchos (1:N) o de muchos a muchos (N:N).
Esa es la relación que se debe mirar para saber donde va la FK y de dónde viene la PK: La FK va donde la cardinalidad de la relación es N. Siempre.
en el caso de las relaciones N:N, eso se construye creando una tabla adicional, desde la cual la relación vuelve a ser 1:N respecto de la tabla referida.

En este sentido, los usuarios tienen perfiles, pero sólo un perfil cada uno.Pero hay N perfiles posibles, entonces la relación Usuario - > perfil es N:1, y por tanto la FK de Perfil va en el usuario, pero no al revés-
¿Se va entendiendo?

por eso tu tabla de perfiles (y la de posts) está mal construida.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 17/12/2013, 10:52
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
La FK va donde la cardinalidad de la relación es N. Siempre.
Ok, hasta ahi me queda claro, ese dato es el q no tengo en cuenta para relacionar las tablas.

Ahora bien, siguiendo con mi ejemplo pero yendo a lo practico y volcando la teoria q me das de ejemplo:
- un user tiene un perfil y un perfil corresponde a un solo usuario, esa relacion la veo como 1:1

Es obvio q van a haber muchos perfiles, como asi tambien, muchos usuarios... y muchos posts y comentarios.

Volviendo al user->perfil, perfil->user, repito, yo lo veo como una relacion 1:1 y no 1:N. En mi logica ya estoy diciendo q un perfil pertenece a un solo usuario.
En cambio, si veo relacion 1:N en decir q un usuario va a tener ninguno/muchos posts, o un post va a tener ninguno/muchos comentarios.

No le encuentro sentido cuando me decis:
Cita:
En este sentido, los usuarios tienen perfiles, pero sólo un perfil cada uno.Pero hay N perfiles posibles, entonces la relación Usuario - > perfil es N:1, y por tanto la FK de Perfil va en el usuario, pero no al revés-
Seguramente me estoy expresando mal:

Yo creo la tabla users y la tabla profile:

Users:
id int() primary key auto_increment... etc,
:


Profiles:
id int() primary key auto_increment... etc,
id_user int()...
:

El articulo q estoy leyendo dice:
Cita:
Una clave foránea es simplemente un campo en una tabla que se corresponde con la clave primaria de otra tabla.
En mi caso, el campo id_user de la tabla Profiles es FK del campo id de la tabla User. Es asi como lo veo yo por el momento.

Vos me decis q asi no, q la logica es N:1 y la FK "deberia" estar en un campo de la tabla Users, o sea, crearia un campo en la tabla Users q se llame profile_id... es correcto lo q entendi?

Podrias aclararme eso?

Gracias
  #8 (permalink)  
Antiguo 17/12/2013, 10:59
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Ademas dice:
Cita:
Las claves foráneas tienen que ver precisamente con la integridad referencial, lo que significa que si una clave foránea contiene un valor, ese valor se refiere a un registro existente en la tabla relacionada.
Yo relaciono perfil con usuario. Es logico q tiene q existir un usuario antes de asignarle un perfil... por lo q perfil tiene q relacionarse con el id del usuario, de lo contrario, no existiria...

Y volviendo al tema principal, el del error, era eso lo q me pasaba. La FK no tenia un valor y no podia ser relacionada
  #9 (permalink)  
Antiguo 17/12/2013, 11:04
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
- un user tiene un perfil y un perfil corresponde a un solo usuario, esa relacion la veo como 1:1
Depende de a qué llames "perfil".
Normalmente, en sistemas multiusuario, "perfil" es un conjunto de permisos y habilitaciones estandarizados que permiten a un usuario dado usar y acceder a recursos de un sistema.
"Perfil", en una red social es algo completamente distinto. Es una descripcion publica de X conjunto de datos que el usuario comparte publica o privadamente.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 17/12/2013, 11:10
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
Iniciado por reborn Ver Mensaje
Ademas dice:


Yo relaciono perfil con usuario. Es logico q tiene q existir un usuario antes de asignarle un perfil... por lo q perfil tiene q relacionarse con el id del usuario, de lo contrario, no existiria...

Y volviendo al tema principal, el del error, era eso lo q me pasaba. La FK no tenia un valor y no podia ser relacionada

Aquí es donde se produce la confusión.
Cuando dices "asignarle un perfil", estás hablando de asignar permisos, no de publicar un cuadro de datos compartibles.
En este caso, por tu descripción, es una red social, y el perfil lo crea el usuario para si mismo. Por ende, como usuario debe existir, y en ese caso el perfil está relacionado con el usuario en una relación 1:1.
Ahora bien, el caso de las cardinalidades 1:1 es un caso que se debe manejar con cuidado, porque puede generar ese tipo de errores de relaciones circulares.
Nunca se debe establecer una relación de FK circular. Eso por lo pronto. Pero en el caso de las 1:1, lo que se debe analizar es cual es la entidad de mayor jerarquía conceptual, y esa será la entidad "padre", por así decirlo.
Básicamente, en una red social, donde el usuario es la entidad fuerte, el perfil es una entidad débil y por tanto carece de PK propia, por lo que hereda la de la entidad fuerte de la que depende.
Para que lo visualices: Un usuario puede existir sin definir el perfil, pero un perfil no puede existir sin pertenecer a un usuario. Por consecuencia, "perfil" es una entidad débil dependiente de "user", y según el modelo relacional, no debe tener PK propia sino que hereda la del usuario.
En ese caso, la única de las dos tablas que posee FK es "perfil", y esta FK apunta ala PK de user.

¿Se entiende?


Detalle importante: Si el perfil es OPCIONAL, entonces no debe ser declarado como NOT NULL en el campo usado como FK de la tabla Perfil.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 17/12/2013, 11:14
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Depende de a qué llames "perfil".
Normalmente, en sistemas multiusuario, "perfil" es un conjunto de permisos y habilitaciones estandarizados que permiten a un usuario dado usar y acceder a recursos de un sistema.
"Perfil", en una red social es algo completamente distinto. Es una descripcion publica de X conjunto de datos que el usuario comparte publica o privadamente.
Ahh, ahi esta el punto ajaja.
Perfil me refiero a lo segundo, datos del usuario q se van a mostrar de forma publica/privada.
A lo primero le llamo rol (super admin, admin, usuario comun)...

Resumiendo: es adecuada la logica q le di a usuario/perfil?, mas alla q al crear las tablas haga una ensalada...
  #12 (permalink)  
Antiguo 17/12/2013, 11:22
Avatar de reborn  
Fecha de Ingreso: febrero-2010
Mensajes: 440
Antigüedad: 11 años, 2 meses
Puntos: 1
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Aquí es donde se produce la confusión.
Cuando dices "asignarle un perfil", estás hablando de asignar permisos, no de publicar un cuadro de datos compartibles.
En este caso, por tu descripción, es una red social, y el perfil lo crea el usuario para si mismo. Por ende, como usuario debe existir, y en ese caso el perfil está relacionado con el usuario en una relación 1:1.
Ahora bien, el caso de las cardinalidades 1:1 es un caso que se debe manejar con cuidado, porque puede generar ese tipo de errores de relaciones circulares.
Nunca se debe establecer una relación de FK circular. Eso por lo pronto. Pero en el caso de las 1:1, lo que se debe analizar es cual es la entidad de mayor jerarquía conceptual, y esa será la entidad "padre", por así decirlo.
Básicamente, en una red social, donde el usuario es la entidad fuerte, el perfil es una entidad débil y por tanto carece de PK propia, por lo que hereda la de la entidad fuerte de la que depende.
Para que lo visualices: Un usuario puede existir sin definir el perfil, pero un perfil no puede existir sin pertenecer a un usuario. Por consecuencia, "perfil" es una entidad débil dependiente de "user", y según el modelo relacional, no debe tener PK propia sino que hereda la del usuario.
En ese caso, la única de las dos tablas que posee FK es "perfil", y esta FK apunta ala PK de user.

¿Se entiende?


Detalle importante: Si el perfil es OPCIONAL, entonces no debe ser declarado como NOT NULL en el campo usado como FK de la tabla Perfil.
Perfecto. Me quedo clarisimo.
Perdon por la confusion pero no manejo lenguaje tan tecnico.

Igual las demas respuestas me abrieron el marote ajaja.
Me voy a poner a leer sobre fundamentos de bases de datos.
  #13 (permalink)  
Antiguo 17/12/2013, 12:20
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 13 años, 5 meses
Puntos: 2656
Respuesta: CakePHP - Cannot add or update a child row: a foreign key constraint fails



SI, Bases de Datos, junto con Redes y Telecomunicaciones, deben ser las áreas más técnicas de este rubro.

__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: add, cakephp, child, constraint, key, php, post, row, update, usuario
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:22.