레일 : dependent => : destroy VS : dependent => : delete_all


192

레일 가이드에서 다음과 같이 설명됩니다.

에 연결된 경우 객체가 추가로 삭제되고 연결된 :dependent => :destroy경우 삭제됩니다.:dependent => :delete_all

맞아요 그러나 파괴와 삭제의 차이점은 무엇입니까? 나는 두 가지를 모두 시도했지만 같은 일을하는 것 같습니다.

답변:


200

차이점은 콜백입니다.

:delete_all응용 프로그램에서 직접 및 SQL에 의해 삭제됩니다 :

DELETE * FROM users where compagny_id = XXXX

를 사용하면 :destroy모든 자녀를 인스턴스화 할 수 있습니다. 따라서 파괴 할 수 없거나 각자 고유 :dependent한 콜백을 호출 할 수 있습니다.


83
자식이 많은 경우 각 자식 개체의 인스턴스화 및 소멸 호출이 느려집니다 (손자가있는 경우 n ^ 2 등). delete_all은 모델에서 콜백을 파괴하기 전 / 후에 신경 쓰지 않거나 신경 쓰지 않는 일종의 "궤도에서 돌림"솔루션입니다.
Ryan Bigg

131

Rails의 모델 연관에서 :dependent옵션을 지정할 수 있으며, 다음 세 가지 형식 중 하나를 취할 수 있습니다.

  • :destroy/:destroy_all연관된 객체는 destroy메소드 를 호출하여이 객체와 함께 파괴됩니다.
  • :delete/:delete_all모든 관련 객체는 :destroy메소드 를 호출하지 않고 즉시 파괴됩니다.
  • :nullify연결된 모든 객체의 외래 키는 콜백 NULL을 호출하지 않고 설정됩니다.save


21
Rails 3.0부터는을 지정할 수도 있습니다 :restrict. : restrict로 설정하면 연결된 개체가있는 경우이 개체를 삭제할 수 없습니다.
RocketR

17
더 없다 :delete또는 :destroy_all그것의 외모 옵션? : dependent 옵션에는 : destroy, : delete_all, : nullify 또는 : restrict (: delete)가 필요합니다.
Mike Campbell

2
@MikeCampbell :delete:destroy_all옵션이 없습니다. 그러나이라고 모델 클래스의 방법이있다 delete하고 destroy_all그래서 혼란의 원인이 될 수 있습니다.
berezovskyi

[: 파괴 : DELETE_ALL : 무효 : restrict_with_error : restrict_with_exception] 따라 옵션 중 하나 여야합니다 : 당신은 몇 가지 더 많은 옵션을 누락 @MikeCampbell의 참조
프라 빈 미 쉬라

30

참조 삭제에게 관련 요소를 파괴DELETE_ALL 자기 테이블에서 여러 데이터를 삭제할 수 있습니다DELETE * FROM table where field = 'xyz'

가능한 옵션 :

소유자가 소멸 될 때 연관된 오브젝트에 발생하는 상황을 제어합니다. 이것들은 콜백으로 구현되며 Rails는 콜백을 순서대로 실행합니다. 따라서 다른 유사한 콜백은 : 종속적 인 동작에 :dependent영향을 줄 수 있으며이 동작은 다른 콜백에 영향을 줄 수 있습니다.

:destroy 관련된 모든 객체도 파괴됩니다.

:delete_all 연관된 모든 객체가 데이터베이스에서 직접 삭제되도록합니다 (따라서 콜백은 실행되지 않습니다).

:nullify외래 키를 NULL로 설정합니다. 콜백이 실행되지 않습니다.

:restrict_with_exception 연관된 레코드가있는 경우 예외가 발생합니다.

:restrict_with_error 연관된 오브젝트가있는 경우 소유자에게 오류가 추가됩니다.

:through옵션 과 함께 사용하는 경우 , 결합 모델의 연관은 belongs_to 여야하고, 삭제 된 레코드는 연관된 레코드가 아닌 결합 레코드입니다.


3

실제로 가장 큰 차이점은 콜백 :delete_all이 사용될 때 호출되지 않는다는 것 입니다. 그러나 :destroy콜백 스택 ( :after_destroy, :after_commit...)이 사용되면 발생합니다.

따라서 touch:모델에서 삭제되는 선언이있는 경우 dependent: :delete_all오히려 'dependent : : destroy' 를 사용하는 것이 좋습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.