삭제와 삭제의 차이점


210

차이점은 무엇입니까

@model.destroy@model.delete

예를 들면 다음과 같습니다.

Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all

하나를 사용하는 것이 정말 중요합니까?

답변:


289

기본적으로 destroy모델에서 콜백을 실행하지만 delete그렇지 않습니다.

로부터 레일 API :

  • ActiveRecord::Persistence.delete

    데이터베이스에서 레코드를 삭제하고이 인스턴스를 고정하여 변경할 수 없으므로 변경하지 않아야 함을 반영합니다. 고정 된 인스턴스를 반환합니다.

    레코드의 기본 키에서 SQL DELETE 문으로 행이 제거되고 콜백이 실행되지 않습니다.

    객체의 before_destroy 및 after_destroy 콜백 또는 임의의 종속 연결 옵션을 적용하려면 #destroy를 사용하십시오.

  • ActiveRecord::Persistence.destroy

    데이터베이스에서 레코드를 삭제하고이 인스턴스를 고정하여 변경할 수 없으므로 변경하지 않아야 함을 반영합니다.

    destroy와 관련된 일련의 콜백이 있습니다. before_destroy 콜백이 false를 반환하면 작업이 취소되고 destroy가 false를 반환합니다. 자세한 내용은 ActiveRecord :: Callbacks를 참조하십시오.


안녕하세요 @ user740584-답변 주셔서 감사합니다. "모델에서 콜백을 실행"한다는 것은 무엇을 의미합니까?
BKSpurgeon

3
그는 액티브 :: 콜백을 의미 @BKSpurgeon : api.rubyonrails.org/classes/ActiveRecord/Callbacks.html를 . 이러한 콜백 중 하나는 특정 조건 model#before_destroy에서 최종 destroy()호출 을 중지하는 데 사용할 수 있습니다 .
Todd

102

delete db에서 현재 객체 레코드 만 삭제하고 db에서 연관된 하위 레코드는 삭제하지 않습니다.

destroy db에서 현재 객체 레코드와 db에서 관련 하위 레코드를 삭제합니다.

그들의 사용은 정말로 중요합니다 :

여러 부모 개체가 공통 자식 개체를 공유하는 경우 destroy특정 부모 개체 를 호출 하면 다른 여러 부모간에 공유되는 자식 개체가 삭제됩니다.


5
훌륭한 답변. 감사합니다. 나는 아이들이 "살해"되었다는 것을 이해하는 용어를 추가 할 것이다. 잔인한 유아 살해.
BKSpurgeon

프로덕션 환경에서 대부분의 경우 '파괴'
Outside_Box

필요하지 않습니다.
Taimoor Changaiz

나는 당신이 사용해야 할 단어 destroy아이들이 아니라 자손 이라고 생각한다 . 문서에 따르면, "속성들로부터 새로운 객체를 생성하고 그것을 파괴한다"고한다. rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Marco Lackovic

12

언제 호출 destroy또는 destroy_allActiveRecord객체의ActiveRecord '파괴'과정이 시작됩니다, 그것은, 클래스 당신에게있는 거 삭제는, 그것이 종속성을 무엇을해야하는지 결정 등의 검증을 통해 실행을 분석

객체 를 호출 delete하거나 delete_all객체 를 호출 할 때는 다른 수준의 작업을 수행하지 않고 db에 대해 쿼리 ActiveRecord를 실행하려고 합니다.DELETE FROM tablename WHERE conditionsActiveRecord


4

네, 두 방법 사이에 큰 차이가 있습니다. 모델 콜백을 호출하지 않고 레코드를 빠르게 삭제하려면 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을 대신 사용하십시오.


2

기본적으로 "삭제"는 레코드를 삭제하기 위해 데이터베이스에 직접 쿼리를 보냅니다. 이 경우 Rails는 레코드에 어떤 속성이 삭제되는지 또는 콜백 (예 : 등 before_destroy) 이 있는지 알 수 없습니다 .

"destroy"메소드는 전달 된 id를 가져 와서 "find"메소드를 사용하여 데이터베이스에서 모델을 가져온 다음 destroy를 호출합니다. 이는 콜백이 트리거되었음을 의미합니다.

콜백을 트리거하지 않거나 성능을 향상 시키려면 "삭제"를 사용하십시오. 그렇지 않으면 (대부분의 경우) "파기"를 사용하려고합니다.


2

이미 많은 답변이 있습니다. 조금 더 뛰고 싶었습니다.

문서 :

has_many의 경우 destroy 및 destroy_all은 항상 제거되는 레코드의 destroy 메소드를 호출하여 콜백이 실행되도록합니다. 그러나 delete 및 delete_all은 : dependent 옵션으로 지정된 전략에 따라 삭제를 수행하거나 : dependent 옵션이 지정되지 않은 경우 기본 전략을 따릅니다. 기본 전략은 기본 전략이 delete_all (콜백을 실행하지 않고 결합 레코드 삭제) 인 has_many : through를 제외하고는 아무 것도하지 않는 것입니다 (부모 ID가 설정된 외래 키는 그대로 두십시오).

deleteverbage를가 다르게 작동 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]]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.