En mi aplicación web generada desde Gii/Giix, al eliminar el registro de una tabla principal, salta una excepción y no controla el error y salta del flujo del programa.
Este es el mensaje que aparece:
If there are several rows in the parent table that have the same referenced key value, InnoDB acts in foreign key checks as if the other parent rows with the same key value do not exist. For example, if you have defined a RESTRICT type constraint, and there is a child row with several parent rows, InnoDB does not permit the deletion of any of those parent rows.
Quiere decir que no permite el borrado del registro principal porque hay una restricción, bien! ¿Yii no controla esto de forma automática en el código autogenerado con Gii?
Da la casualidad que justo esta tabla de la que intento borrar (Language) es la única que tiene una restricción de borrado (On delete: Restrict). El resto de relaciones del modelo de datos, es decir de las Claves Foraneas (Foreign Keys) del modelo, las deje para que actaulizaran y borraran en cascada (On Delete: Cascade, On Update: Cascade) y funcionan correctamente (borrando todas las filas).
Mi pregunta es: ¿Yii no está preparado para controlar estas excepciones de la tabla de datos desde el modelo o el controlador?
En ese caso, ¿tengo que preocuparme por modificar el controlador del modelo restringido para controlar la excepción?
De la mano de los creadores de giix (el generador de código de yii extendido) comentan que este NO controla esta excepción generada en la base de datos. Con lo cual, me arriesgo y aseguro que el genérico (gii, que es más limitado) probablamente tampoco lo haga.
Comentan que en realidad, más que una limitación es un error de concepto al gestionar nuestra base de datos, donde la base de datos de InnodDB bloquea el borrado o actualización, para la opción de ‘Restrict’ o ‘No Action’.
Veamos esto en un ejemplo: Se tienen dos tablas relacionadas, una tabla ‘Lenguajes’ y otra de ‘Descripciones’ para gestionar varios idiomas. Entonces si propagamos la FK (relación de clave extranjera) de la tabla ‘Descripciones’ a la tabla ‘Lenguajes’, y la creamos con lcomo Delete: ‘Restrict’ o ‘No Action’. Sucede que si queremos borrar un lenguaje que ya tiene registros relacionados en la tabla ‘Descripciones’, InnoDB no permite el borrado de ese registro y Yii, en vez de controlarlo extiende la extensión, saltandose el flujo, y mostrando el error SQL generado al borrar.
Lo cual quiere decir, que tiene que ser uno mismo quien se encarge de validar estos mensajes, manejando manualmente excepciones desde el controlador del modelo oportuno, para cubrir esta brecha en nuestro código.
Como menciona @Totto, es cuestión de motor de base de datos.
Una alternativa es sobrecargar el método "delete" en el modelo en cuestión verificando los campos foráneos y eliminándolos desde PHP (asegurándose de hacer las validaciones necesarias).
Otra alternativa es habilitar la eliminación en cascada (con los respectivos riesgos que ello implica) desde la BD.