Soft delete với gem paranoia
Bài đăng này đã không được cập nhật trong 7 năm
Soft delete là cách đơn giản để bảo vệ an toàn cho dữ liệu của hệ thống. Bằng việc không xóa hoàn toàn record trong Database, mà chỉ đưa nó về một trạng thái nào đó được quy ước là đã xóa, tức không còn tồn tại trong các câu truy vấn thông thường.
Trước khi đi vào tìm hiểu cách sử dụng gem paranoia
để thực hiện soft delete
, chúng ta hãy cân nhắc một số điểm sau trước khi quyết định sử dụng soft delete
trong hệ thống của mình.
- Nếu thực hiện
hard delete
, tức xóa hoàn toàn record trong database bằng câu truy vấnDELETE
quen thuộc, rất đơn giản chúng ta đã xóa hoàn toàn các dữ liệu cần loại bỏ. Không còn dữ liệu dư thừa trong hệ thống, nó sẽ chạy nhanh hơn; nhưng cùng với điều đó là chúng ta không thể khôi phục lại dữ liệu đã xóa, dữ liệu đó đã mất vĩnh viễn nếu bạn không có bản backup nào cho nó. - Thay vì dùng
hard delete
, chúng ta sử dụngsoft delete
để giữ lại các bản ghi đã bị loại bỏ. Có một vấn đề xảy ra: chúng ta đã không xóa bất kỳ của relation của bản ghi đã xóa, mà có thể là những thứ sẽ gây ra lỗi nghiêm trọng mà chúng ta không lường đến. Để khắc phục việc này, bạn sẽ phải chuyển việc xử lý những rắc rối đó sang cho ứng dụng của mình, mà chưa chắc rằng các cách xử lý đó sẽ khắc phục hết những rắc rối do những record relation đó sinh ra. Cùng với đó là việc các query không được xóa sẽ làm cho hệ thống của chúng ta nặng nề hơn, dẫn đến việc thực hiện các query khác cũng chậm hơn.
-
Tìm hiểu cách thực hiện của gem
paranoia
Paranoia thực hiện soft delete bằng cách thêm 1 column
deleted_at
với giá trị mặc định lànil
trong table mà chúng ta cầnsoft delete
tại đó. Như vậy khi gọi hàmdestroy
trong ActiveRecord object của model đó, record đó sẽ không bị xóa đi mà sẽ được update trườngdeleted_at
với giá trị được quy định sẵn. Nếu record có chứa liên kếthas_many
, các record có tên trong quan hệ has_many đều cũng sẽ đượcsoft delete
.Để cài đặt gem
paranoia
, ta thêm tên gem vàoGemfile
:
# Với Rails 3:
gem "paranoia", "~> 1.0"
# Với Rails 4:
gem "paranoia", "~> 2.0"
# Với Rails 5:
gem "paranoia", "~> 2.2.0.pre"
# Hoặc:
gem "paranoia", github: "rubysherpas/paranoia", branch: "rails3"
gem "paranoia", github: "rubysherpas/paranoia", branch: "rails4"
gem "paranoia", github: "rubysherpas/paranoia", branch: "rails5"
Sau đó chạy bundle ínstall
để cài đặt.
Chạy migrate để thêm column deleted_at
vào table:
bin/rails generate migration AddDeletedAtToClient deleted_at:datetime:index
# Client là tên table cần soft delete
Thêm acts_as_paranoid
vào model để thực hiện soft delete với ActiveRecord
- Cách sử dụng gem
Sau khi hoàn tất việc cài đặt, khi gọi delete
sẽ update gía trị cho trường deleted_at
:
`>>` client.deleted_at
# => nil
`>>` client.destroy
# => client
`>>` client.deleted_at
# => [current timestamp]
Để thực hiện việc xóa hoàn toàn record, chúng ta chạy lệnh really_destroy!
:
>> client.deleted_at
# => nil
>> client.really_destroy!
# => client
Để truy vấn tất cả các record đã bị xóa bởi soft delete
:
Client.only_deleted
Để truy vấn tất cả các record đang tồn tại trong database, bao gồm đã xóa và chưa xóa:
Client.with_deleted
Để kiểm tra xem record đó đã được soft delete hay chưa:
client.paranoia_destroyed?
# or
client.deleted?
Để khôi phục record đã bị soft delete:
Client.restore(id)
# or
client.restore
# or
Client.restore([id1, id2, ..., idN])
Nếu muốn khôi phục cả những record có quan hệ dependently destroyed
:
Client.restore(id, :recursive => true)
# or
client.restore(:recursive => true)
All rights reserved