Al eliminar las asociaciones hasOne o hasMany, ¿se debe establecer la ForeignKey en NULL?

StackOverflow https://stackoverflow.com/questions/148169

Pregunta

Dado:

  

Grupo tiene muchas personas

pero la relación es independiente (es decir, las personas pueden existir sin pertenecer a un grupo), ¿la clave externa en la tabla de personas (es decir, group_id) se debe establecer en 0 (o NULL) al eliminar un grupo? Si no lo hace, la persona tratará de pertenecer a un grupo que no existe.

La razón por la que pregunto es que este es el comportamiento predeterminado en Cakephp. Si establece dependiente en verdadero, eliminará los modelos asociados, pero si se establece en falso, dejará el modelo asociado intacto.

¿Fue útil?

Solución

Sí, las claves foráneas deben establecerse en NULL (o 0, si este es su valor 'sin grupo' elegido) o perderá la integridad referencial. Si su base de datos lo admite, debería poder establecer un desencadenante 'Al eliminar' o una regla en cascada en su marco para hacer cumplir esto. Y el comportamiento en CakePHP parece correcto. Si el valor es dependiente, debe eliminarse al borrarse. Si no es dependiente, debe proporcionar una lógica de comportamiento adicional en cuanto a la acción correcta que debe realizar (en este caso, desea establecer todos los valores en NULL. En otros casos, es posible que desee establecer un grupo "predeterminado") , etc.)

Otros consejos

En una palabra, sí. Si deja la clave foránea en la tabla de personas, se perderá integridad referencial dentro de la base de datos.

> Si no lo hace, la persona intentará pertenecer a un grupo que no existe.

También hay un escenario peor: en el futuro puede aparecer un nuevo grupo B que reutilizará la identificación del grupo eliminado A. Entonces, todos los usuarios del grupo A anterior serán "mágicamente". alistado en el nuevo grupo B.

Una forma alternativa y más estable de implementar una situación en la que ambas entidades son independientes sería eliminar la clave externa por completo de Person y crear una tabla de unión group_persons. De esta manera, no tendrá que preocuparse por la integridad de su referencia cuando elimine un grupo. Cuando eliminas un grupo, la asociación se eliminará de group_persons.

La tabla se vería así

id, group_id, person_id

El modelo group_persons se verá así

Person hasMany GroupPerson
Group hasMany GroupPerson
GroupPerson belongsTo Person, Group

Si desea que la Persona solo pueda estar en un grupo a la vez, establezca una regla de validación única en GroupPerson.

var $validate=array(
    'person_id'=>array(
        array(
        'rule'=>'isUnique',
        'message'=>'This person is already in a group.'
        )
    )
);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top