iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Modern Web

網頁前後端寶石庫-礦坑補完計畫系列 第 29

Day 29 Rails soft delete - paranoia

記得當初上課時第一次聽到軟刪除這個詞蠻震驚的,沒想到網路世界是這麼可怕的阿。

阿修說文解字

soft delete vs hard delete

網路上的刪除有分兩種,軟刪除以及硬刪除:

  • 軟刪除:當使用者案下刪除鍵後,後台只是用某種方式讓使用者看不到資訊而已,但其實資料還是存在於資料庫內,像有些通訊軟體的收回可能就是軟刪除。
    • 好處:後台幫使用者把資料都存的好好的,使用者的資料還救得回來。
    • 壞處:使用者在網路上做的任何事情都會被記錄下來,所以沒事不要亂上傳東西到網路上阿,你不會知道該網站的後台是怎麼處理你的資料的。
  • 硬刪除:當使用者案下刪除鍵後,就真的從資料庫刪除資料了,想救也救不回來。

Rails 的 soft delete

在 Rails 內,當你使用 destroy 這個方法後就會直接從資料庫刪除檔案,也就是硬刪除。
假如想要使用軟刪除可以使用 paranoia 套件搭配 acts_as_paranoid。
現在我想把一個筆記的刪除變成軟刪除,我可以這樣做:

  1. 安裝 paranoia 套件,接著 bundle install
  gem 'paranoia', '~> 2.4', '>= 2.4.3'           # 目前 2.4.3 為最新版
  1. 先用終端機建立一個 migration,deleted_at 這個名字可以隨意取,主要是要讓自己或別人看得懂這個 migration 是在做甚麼。
  rails g migration deleted_at
  1. 在 migration 檔裡面對 note model 新增 deleted_at 欄位,型態為 datetime,會使用 deleted_at 跟 datetime 是因為 paranoia 這個套件的慣例就是這樣,所以我們要照著設定。
class DeletedAt < ActiveRecord::Migration[6.1]
  def change
    add_column :notes, :deleted_at, :datetime  # 新增欄位: 資料表名稱,欄位名稱,型態
    add_index :notes, :deleted_at              # 新增索引: 加快查詢,概念有點像寫書會加的附錄
  end
end

4.1 在 note model 新增 default_scope 讓所有的筆記都先預設為顯示 deleted_at 欄位裡面值是 nil 的筆記。

  default_scope { where(deleted_at: nil) }

4.2 或是直接在 note model 輸入 acts_as_paranoid 也可以完成上述的行為。

  acts_as_paranoid
  1. 在 note controller 把 @note.destroy 改成 @note.update(deleted_at: Time.now),從原本的刪除筆記變成更新筆記的狀態,因為剛剛預設是 nil 可以看的到,點下去後會變成現在的時間,也就是有值的狀態,就會變成看不到此篇筆記。
def destroy
  @note.update(deleted_at: Time.now)
end

=> 如此一來以後使用 destroy 方法刪除檔案時就會變成軟刪除了。

Rails 的 hard delete

那假如我想用硬刪除該怎麼辦呢?
paranoia 幫你新增了一個方法叫 really_destroy!
使用他就可以變成硬刪除了。

參考:
[1]paranoia套件


上一篇
Day 28 Rails shallow nesting
下一篇
Day 30 Rails dependent destroy
系列文
網頁前後端寶石庫-礦坑補完計畫30

尚未有邦友留言

立即登入留言