소프트 삭제(Soft-deletion)는 데이터를 영구적으로 삭제하지 않고, 복구 가능한 상태로 '숨기는' 데이터 관리 기법입니다. 이는 Windows의 휴지통이나 이메일 보관함과 유사한 개념으로, 사용자 실수로 인한 데이터 손실을 방지하고 데이터 복구 기회를 제공하는 데 중요한 목적이 있습니다. 데이터베이스 기반 애플리케이션에서 소프트 삭제는 일반적으로 레코드에 특정 타임스탬프 컬럼(예: deleted_at, discarded_at)을 추가하여 구현되며, 이 컬럼의 값 유무로 데이터의 활성/비활성 상태를 구분합니다.
데이터베이스 기반 애플리케이션에서 소프트 삭제는 해당 레코드에 타임스탬프 컬럼을 추가하고, 이 컬럼에 값이 설정되면 ‘삭제된’ 것으로 간주하여 쿼리 시 제외하는 방식으로 구현됩니다. Solidus 및 Spree와 같은 플랫폼에서는 초기에 소프트 삭제 기능을 직접 구현하다가, 이후 Paranoia 젬을 도입하여 추상화된 기능을 제공했습니다. Paranoia 젬은 deleted_at
컬럼을 사용하며, ActiveRecord 모델에 포함될 때 default_scope
와 #destroy
메서드를 오버라이드하여 소프트 삭제를 구현했습니다. #destroy
또는 #destroy!
호출 시 레코드를 실제로 삭제하는 대신 deleted_at
타임스탬프를 설정하여 숨기며, 수정된 default_scope
는 기본적으로 숨겨진 레코드를 쿼리 결과에서 제외합니다. 그러나 이러한 default_scope
오버라이드는 때때로 예상치 못한 동작을 유발하고 디버깅을 어렵게 만드는 단점이 있었습니다. 이러한 Paranoia의 단점을 개선하기 위해 Discard 젬이 개발되었습니다. Discard 젬은 Paranoia와 달리 모델의 default_scope
나 #destroy
메서드를 오버라이드하지 않습니다. 대신, discarded_at
컬럼을 사용하며, 유지된 레코드를 위한 .kept
스코프와 삭제된 레코드를 위한 .discarded
스코프를 명시적으로 추가합니다. 레코드를 소프트 삭제하려면 #discard
메서드를 사용합니다. 이러한 명시적인 접근 방식은 코드의 가독성을 높이고 동작을 예측하기 쉽게 만듭니다. Discard를 모델에 적용하는 절차는 간단합니다. discarded_at:datetime:index
컬럼을 추가하는 데이터베이스 마이그레이션을 실행한 후, 해당 ActiveRecord 모델 클래스에 include Discard::Model
을 추가하면 됩니다. Solidus와 같이 기존 Paranoia의 default_scope
동작 방식에 익숙한 환경에서는 커스텀 모듈을 정의하여 Discard의 기본 스코프 설정을 변경함으로써 호환성을 유지할 수 있습니다.
결론적으로, Discard 젬은 Rails 애플리케이션에 소프트 삭제 기능을 구현하기 위한 효과적이고 명확한 대안을 제시합니다. Paranoia 젬의 `default_scope` 오버라이드로 인한 혼란을 해소하고, 명시적인 스코프와 메서드를 통해 개발자가 소프트 삭제 동작을 더 쉽게 이해하고 제어할 수 있도록 돕습니다. 소프트 삭제 기능을 사용자 데이터에 적용할 경우에는 GDPR과 같은 개인정보 보호 규정을 준수하여, 사용자의 삭제 요청 시 소프트 삭제된 데이터 역시 영구적으로 삭제해야 한다는 점을 반드시 유념해야 합니다.