Respuestas:
Básicamente destroy
ejecuta cualquier devolución de llamada en el modelo mientras delete
no lo hace.
De la API de Rails :
ActiveRecord::Persistence.delete
Elimina el registro en la base de datos y congela esta instancia para reflejar que no se deben realizar cambios (ya que no se pueden persistir). Devuelve la instancia congelada.
La fila simplemente se elimina con una instrucción DELETE de SQL en la clave primaria del registro, y no se ejecutan devoluciones de llamada.
Para aplicar las devoluciones de llamada antes_destruir y después_destruir del objeto o cualquiera: opciones de asociación dependientes, use #destroy.
ActiveRecord::Persistence.destroy
Elimina el registro en la base de datos y congela esta instancia para reflejar que no se deben realizar cambios (ya que no se pueden persistir).
Hay una serie de devoluciones de llamada asociadas con destruir. Si la devolución de llamada before_destroy devuelve falso, la acción se cancela y destruir devuelve falso. Vea ActiveRecord :: Callbacks para más detalles.
model#before_destroy
que se puede usar para detener la destroy()
llamada final bajo ciertas condiciones.
delete
solo eliminará el registro de objeto actual de db pero no sus registros secundarios asociados de db.
destroy
eliminará el registro de objeto actual de db y también su registro secundario asociado de db.
Su uso realmente importa:
Si sus múltiples objetos primarios comparten objetos secundarios comunes, al invocar destroy
un objeto primario específico se eliminarán los objetos secundarios que se comparten entre otros múltiples padres.
destroy
es descendientes , no hijos : de acuerdo con la documentación, destruir "crea un nuevo objeto a partir de los atributos, y luego llama a destruir en él". rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Cuando invoca destroy
o destroy_all
sobre un ActiveRecord
objeto, elActiveRecord
se inicia el proceso de 'destrucción', analiza la clase que está eliminando, determina qué debe hacer para las dependencias, ejecuta validaciones, etc.
Cuando invoca delete
o delete_all
sobre un objeto, ActiveRecord
simplemente intenta ejecutar la DELETE FROM tablename WHERE conditions
consulta en el DB, sin realizar otras ActiveRecord
tareas de nivel.
Sí, existe una gran diferencia entre los dos métodos. Use delete_all si desea que los registros se eliminen rápidamente sin que se llame a las devoluciones de llamada del modelo
Si te interesan las devoluciones de llamada de tus modelos, usa destroy_all
De los documentos oficiales
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all (condiciones = nulo) public
Destruye las condiciones de coincidencia de registros creando instancias de cada registro y llamando a su método de destrucción. Las devoluciones de llamada de cada objeto se ejecutan (incluidas: opciones de asociación dependiente y métodos de observador before_destroy / after_destroy). Devuelve la colección de objetos que fueron destruidos; cada uno se congelará para reflejar que no se deben realizar cambios (ya que no se pueden persistir).
Nota: La creación de instancias, la ejecución de devolución de llamada y la eliminación de cada registro pueden llevar mucho tiempo cuando se eliminan muchos registros a la vez. Genera al menos una consulta DELETE de SQL por registro (o posiblemente más, para aplicar sus devoluciones de llamada). Si desea eliminar muchas filas rápidamente, sin preocuparse por sus asociaciones o devoluciones de llamada, use delete_all en su lugar.
Básicamente, "eliminar" envía una consulta directamente a la base de datos para eliminar el registro. En ese caso, Rails no sabe qué atributos hay en el registro que está eliminando ni si hay devoluciones de llamada (como before_destroy
).
El método "destroy" toma la identificación pasada, recupera el modelo de la base de datos usando el método "find" y luego llama a destroy en ese caso. Esto significa que se activan las devoluciones de llamada.
Desea usar "eliminar" si no desea que se activen las devoluciones de llamada o si desea un mejor rendimiento. De lo contrario (y la mayoría de las veces) querrá usar "destruir".
Muchas respuestas ya; quería saltar con un poco más.
docs :
Para has_many, destroy y destroy_all siempre llamará al método de destrucción de los registros que se eliminan para que se ejecuten las devoluciones de llamada. Sin embargo, delete y delete_all harán la eliminación de acuerdo con la estrategia especificada por la opción: dependiente, o si no se da la opción: dependiente, entonces seguirá la estrategia predeterminada. La estrategia predeterminada es no hacer nada (dejar las claves foráneas con los ID de los padres establecidos), excepto has_many: through, donde la estrategia predeterminada es delete_all (eliminar los registros de unión, sin ejecutar sus devoluciones de llamada).
El delete
verbage funciona de manera diferente para ActiveRecord::Association.has_many
y ActiveRecord::Base
. Para este último, eliminar ejecutará SQL DELETE
y omitirá todas las validaciones / devoluciones de llamada. El primero se ejecutará en función de la :dependent
opción pasada a la asociación. Sin embargo, durante las pruebas, encontré el siguiente efecto secundario donde las devoluciones de llamada solo se ejecutaron delete
y nodelete_all
dependent: :destroy
Ejemplo:
class Parent < ApplicationRecord
has_many :children,
before_remove: -> (_) { puts "before_remove callback" },
dependent: :destroy
end
class Child < ApplicationRecord
belongs_to :parent
before_destroy -> { puts "before_destroy callback" }
end
> child.delete # Ran without callbacks
Child Destroy (99.6ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 21]]
> parent.children.delete(other_child) # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 22]]
> parent.children.delete_all # Ran without callbacks
Child Destroy (1.0ms) DELETE FROM "children" WHERE "children"."parent_id" = $1 [["parent_id", 1]]