[ruby-on-rails] 삭제와 삭제의 차이점
차이점은 무엇입니까
@model.destroy
과 @model.delete
예를 들면 다음과 같습니다.
Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all
하나를 사용하는 것이 정말 중요합니까?
답변
기본적으로 destroy
모델에서 콜백을 실행하지만 delete
그렇지 않습니다.
로부터 레일 API :
-
ActiveRecord::Persistence.delete
데이터베이스에서 레코드를 삭제하고이 인스턴스를 고정하여 변경할 수 없으므로 변경하지 않아야 함을 반영합니다. 고정 된 인스턴스를 반환합니다.
레코드의 기본 키에서 SQL DELETE 문으로 행이 제거되고 콜백이 실행되지 않습니다.
객체의 before_destroy 및 after_destroy 콜백 또는 임의의 종속 연결 옵션을 적용하려면 #destroy를 사용하십시오.
-
ActiveRecord::Persistence.destroy
데이터베이스에서 레코드를 삭제하고이 인스턴스를 고정하여 변경할 수 없으므로 변경하지 않아야 함을 반영합니다.
destroy와 관련된 일련의 콜백이 있습니다. before_destroy 콜백이 false를 반환하면 작업이 취소되고 destroy가 false를 반환합니다. 자세한 내용은 ActiveRecord :: Callbacks를 참조하십시오.
답변
delete
db에서 현재 객체 레코드 만 삭제하고 db에서 연관된 하위 레코드는 삭제하지 않습니다.
destroy
db에서 현재 객체 레코드와 db에서 관련 하위 레코드를 삭제합니다.
그들의 사용은 정말로 중요합니다 :
여러 부모 개체가 공통 자식 개체를 공유하는 경우 destroy
특정 부모 개체 를 호출 하면 다른 여러 부모간에 공유되는 자식 개체가 삭제됩니다.
답변
언제 호출 destroy
또는 destroy_all
온 ActiveRecord
객체의ActiveRecord
‘파괴’과정이 시작됩니다, 그것은, 클래스 당신에게있는 거 삭제는, 그것이 종속성을 무엇을해야하는지 결정 등의 검증을 통해 실행을 분석
객체 를 호출 delete
하거나 delete_all
객체 를 호출 할 때는 다른 수준의 작업을 수행하지 않고 db에 대해 쿼리 ActiveRecord
를 실행하려고 합니다.DELETE FROM tablename WHERE conditions
ActiveRecord
답변
네, 두 방법 사이에 큰 차이가 있습니다. 모델 콜백을 호출하지 않고 레코드를 빠르게 삭제하려면 delete_all을 사용하십시오.
모델 콜백에 관심이 있다면 destroy_all을 사용하십시오.
공식 문서에서
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all (조건 = nil) 공개
각 레코드를 인스턴스화하고 destroy 메소드를 호출하여 조건과 일치하는 레코드를 삭제합니다. 각 객체의 콜백이 실행됩니다 (: 종속 연결 옵션 및 before_destroy / after_destroy Observer 메소드 포함). 파괴 된 객체의 컬렉션을 반환합니다. 변경 될 수 없음을 반영하기 위해 각각 동결됩니다 (지속될 수 없기 때문에).
참고 : 한 번에 많은 레코드를 제거 할 때 각 레코드의 인스턴스화, 콜백 실행 및 삭제에 시간이 오래 걸릴 수 있습니다. 레코드 당 하나 이상의 SQL DELETE 쿼리를 생성합니다 (또는 콜백을 강화하기 위해 더 많을 수도 있음). 연관이나 콜백에 대한 걱정없이 많은 행을 빠르게 삭제하려면 delete_all을 대신 사용하십시오.
답변
기본적으로 “삭제”는 레코드를 삭제하기 위해 데이터베이스에 직접 쿼리를 보냅니다. 이 경우 Rails는 레코드에 어떤 속성이 삭제되는지 또는 콜백 (예 : 등 before_destroy
) 이 있는지 알 수 없습니다 .
“destroy”메소드는 전달 된 id를 가져 와서 “find”메소드를 사용하여 데이터베이스에서 모델을 가져온 다음 destroy를 호출합니다. 이는 콜백이 트리거되었음을 의미합니다.
콜백을 트리거하지 않거나 성능을 향상 시키려면 “삭제”를 사용하십시오. 그렇지 않으면 (대부분의 경우) “파기”를 사용하려고합니다.
답변
이미 많은 답변이 있습니다. 조금 더 뛰고 싶었습니다.
문서 :
has_many의 경우 destroy 및 destroy_all은 항상 제거되는 레코드의 destroy 메소드를 호출하여 콜백이 실행되도록합니다. 그러나 delete 및 delete_all은 : dependent 옵션으로 지정된 전략에 따라 삭제를 수행하거나 : dependent 옵션이 지정되지 않은 경우 기본 전략을 따릅니다. 기본 전략은 기본 전략이 delete_all (콜백을 실행하지 않고 결합 레코드 삭제) 인 has_many : through를 제외하고는 아무 것도하지 않는 것입니다 (부모 ID가 설정된 외래 키는 그대로 두십시오).
delete
verbage를가 다르게 작동 ActiveRecord::Association.has_many
하고 ActiveRecord::Base
. 후자의 경우 삭제는 SQL DELETE
모든 유효성 검사 / 콜백을 실행 하고 무시합니다. 전자는 :dependent
연결에 전달 된 옵션을 기반으로 실행됩니다 . 그러나 테스트 중에 콜백이 실행 delete
되지 않고 다음과 같은 부작용이 발생했습니다.delete_all
dependent: :destroy
예:
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]]