ruby on rails - solucion - ERROR: eliminar en la tabla viola la restricción de clave externa. La identificación de la clave aún se referencia desde la tabla(muchos)
no puede adicionar clave extranjera constraint (6)
Estoy trabajando con Rails y PostgreSQL y tengo una relación básica de uno a varios, una Auction
tiene muchas Bid
. Sin embargo, cuando intento eliminar una subasta (que tiene ofertas presentes), aparece el siguiente error:
ERROR: actualizar o eliminar en la tabla "subastas" viola la restricción de clave externa "fk_rails_43e9021cbf" en la tabla "ofertas". DETAIL: Key (id) = (1) todavía se referencia desde la tabla "ofertas".
Eliminar subastas sin ofertas no genera ningún error.
La parte que me confunde es que dentro de mi modelo de Auction
, tengo:
has_many :bids, dependent: :destroy
Como tengo una cláusula de destrucción dependiente, ¿por qué sigo recibiendo este error?
EDITAR: He tratado de eliminar toda la base de datos, luego volver a crear / volver a migrar todo, aún así obtener el mismo error.
¿Estás por casualidad usando la joya de la paranoia o algo así?
Si sus bids
son paranoid
y las auctions
no, puede encontrarse con este error.
Esto sucedería porque cuando los rieles ejecutan el dependent: destroy
, eliminaría las ofertas, pero en realidad todavía existen en el DB (simplemente tienen el deleted_at
columnas deleted_at
). Por lo tanto, la restricción de clave externa fallará.
¿Estás utilizando delete
o destroy
para eliminar los objetos? Creo que estás utilizando delete
y quieres usar destroy
Desde Rails v4.2 puedes hacer esto:
Crear una migración para actualizar las claves externas
20160321165946_update_foreign_key.rb
class UpdateForeignKey < ActiveRecord::Migration
def change
# remove the old foreign_key
remove_foreign_key :posts, :users
# add the new foreign_key
add_foreign_key :posts, :users, on_delete: :cascade
end
end
Marc Busqué tiene un muy buen artículo sobre este problema que podría ayudar.
"Cuando ActiveRecord encuentra una violación de clave externa, genera una excepción ActiveRecord :: InvalidForeignKey. Incluso si en su documentación solo dice que se genera cuando un registro no puede insertarse o actualizarse porque hace referencia a un registro inexistente, el hecho es que también se usa en el caso que nos interesa ".
Con eso y un rescue_from podemos simplemente agregar ApplicationController o una preocupación del controlador:
rescue_from ''ActiveRecord::InvalidForeignKey'' do
# Flash and render, render API json error... whatever
end
Mi problema es que estoy usando @ auction.delete (visible en la captura de pantalla que publiqué) cuando intento eliminar un registro.
Eliminar ignorará las devoluciones de llamada que tengo en su lugar. Entonces, aunque tengo una cláusula de destrucción dependiente, no se está llamando, por lo tanto, Rails está lanzando un error. Si / Cuando cambié el código para leer @ auction.destroy, se invocó el call-back y se solucionó el problema.
Referencia: diferencia entre Destruir y Eliminar
Su error es de la base de datos no rieles. Primero debe eliminar las ofertas en su aplicación o cambiar la restricción de clave externa en la base de datos para