PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PG::ForeignKeyViolation:ERRO:atualizar ou excluir na tabela xxx viola a restrição de chave estrangeira


Do manual fino :

Então :delete_all cuida de chaves estrangeiras, mas, como nenhum retorno de chamada é chamado, ele só vai até um nível de profundidade. Então isso em Company :
has_many :projects, dependent: :delete_all

significa que chamar #destroy em uma empresa excluirá diretamente os projects associados do banco de dados. Mas isso não verá isso:
has_many :tasks, dependent: :delete_all

que você tem em Project e você acaba tentando excluir projetos que ainda são referenciados em tasks como a mensagem de erro indica.

Você pode mudar todas as suas associações para dependent: :destroy , isso puxará tudo do banco de dados antes de destruí-los e os retornos de chamada serão chamados (o que carregará mais coisas do banco de dados apenas para destruí-los, o que carregará mais coisas do banco de dados ...). O resultado final será muita atividade do banco de dados, mas todas as chaves estrangeiras serão seguidas corretamente.

Alternativamente, você pode colocar a lógica dentro do banco de dados onde ela normalmente pertence especificando on delete cascade nas restrições de chave estrangeira :

Sua add_foreign_key chamadas ficariam assim:
add_foreign_key "projects", "companies", on_delete: :cascade
add_foreign_key "tasks", "projects", on_delete: :cascade
add_foreign_key "task_times", "tasks", on_delete: :cascade

nesse caso. Você provavelmente gostaria de deixar o dependent: :delete_all s em seus modelos como um lembrete do que está acontecendo, ou você pode deixar um comentário.