Ao excluir hasOne ou hasMany associações, caso o foreignKey ser definido como NULL?
-
02-07-2019 - |
Pergunta
Dada:
Grupo hasMany Pessoas
mas a relação é independente (ie. Pessoas podem existir sem pertencer a um grupo), deve a chave estrangeira na tabela de pessoas (ou seja group_id) ser definido como 0 (ou NULL) ao excluir um grupo? Se não o fizer, a pessoa vai tentar pertencer a um grupo que existem does't.
A razão que eu peço é que este é o comportamento padrão no CakePHP. Se você definir dependente como verdadeiro, ele irá apagar os modelos associados, mas se ele é definido como falso ele vai deixar o modelo associado intocado.
Solução
Sim, as chaves estrangeiras deve ser definido como NULL (ou 0, se este é o seu 'nenhum grupo' valor escolhido) ou você perde a integridade referencial. Se o seu banco de dados suporta-lo, você deve ser capaz de definir uma 'On delete' gatilho ou uma regra cascata em sua estrutura para fazer cumprir esta. E o comportamento no CakePHP parece correto. Se o valor é dependente, então ele deve ser removido na eliminação. Se não é dependente, então você precisa dar lógica comportamento extra como a ação correta a ser tomada (neste caso, você deseja definir todos os valores para NULL. Em outros casos, você pode querer definir a um grupo 'default' , etc)
Outras dicas
Em uma palavra, sim. Deixando a chave estrangeira na tabela pessoas resultaria na perda de integridade referencial dentro do banco de dados.
> Se você não, a pessoa vai tentar pertencer a um grupo que existem does't.
Há também um cenário pior:. No futuro, um novo grupo B pode parecer que vai reutilizar o ID de grupo excluído A. Em seguida, todos os usuários ex-grupo A será "magicamente" se alistou no novo grupo B
Uma alternativa, maneira mais estável para implementar uma situação onde ambas as entidades são independentes seria remover a chave estrangeira inteiramente de Pessoa e criar uma junção group_persons tabela. Desta forma, você não terá que se preocupar com a sua integridade referência ao excluir um grupo. Quando você exclui um grupo, a associação seria excluído do group_persons.
A tabela ficaria assim
id, group_id, person_id
O modelo group_persons será parecido com este
Person hasMany GroupPerson
Group hasMany GroupPerson
GroupPerson belongsTo Person, Group
Se você quer que a pessoa apenas para ser capaz de estar em um grupo de cada vez, defina uma regra de validação única no GroupPerson.
var $validate=array(
'person_id'=>array(
array(
'rule'=>'isUnique',
'message'=>'This person is already in a group.'
)
)
);