iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
SideProject30

用 Rails 打造你的電商網站系列 第 9

Day 09 你看到的刪除不是刪除

  • 分享至 

  • xImage
  •  

前置作業:在 index 頁面的每個商品加上編輯連結以及刪除連結

當我們不小心將一筆商品刪除,結果兩個月後卻發現又要再賣一次,

這時候還要再上架一次,雖然說沒有很麻煩,

但如果這情境套用到比較重要的資訊時,就會讓人頭痛

或者是當某些資料有爭議時,不過他已經被刪除了,這時候就會更讓人傷腦筋

軟刪除可以解決這個問題

軟刪除是什麼意思

我們還是會把檔案刪除,不過在資料庫中的資料並沒有被刪除

也就是說,資料不會被刪掉,只是我們在畫面中看不到

怎麼實作軟刪除

軟刪除其實不難,我們可以直接用手刻的

step 1. 增加一個 migration 並且在商品 model 個別加上一個欄位 deleted_at

class AddDeletedAtToProduct < ActiveRecord::Migration[7.0]
  def change
    add_column :drinks, :deleted_at, :datetime
    add_column :desserts, :deleted_at, :datetime
  end
end

我們在刪除的時候只會更新這個欄位

step 2. 調整 destroy 方法

# app/controllers/drinks_controller.rb

  def destroy
    @drink.update(deleted_at: Time.current)
    redirect_to drinks_path
  end

step 3. 調整 index 撈資料的方法,方法放在 model

# app/controllers/drinks_controller.rb

  def index
    @pagy, @drinks = pagy(Drink.available_drink, link_extra: 'data-remote="true"')
  end

step 4. 到 model 寫方法

# app/models/drink.rb

class Drink < ApplicationRecord

  scope :available_drink, -> { where(deleted_at: nil )}
end

當然我們也可以用套件來達成這個功能

paranoia

為什麼使用 paranoia

其實就是方便、不需要寫太多程式碼而已

怎麼用

step 1. 安裝 paranoia

gem "paranoia"

step 2. 新增欄位

class AddDeletedAtToDrinks < ActiveRecord::Migration
  def change
    add_column :drinks, :deleted_at, :datetime
    add_index :drinks, :deleted_at
  end
end

step 3. 在 model 加上設定

# app/models/drink.rb

class Drink < ApplicationRecord
  acts_as_paranoid
  
  ...
end

step 4. 刪除方法

如果要用軟刪除,就使用 destroy 方法

# app/controllers/drinks_controller.rb

  def destroy
    @drink.destroy
    redirect_to drinks_path
  end

我們刪的是最後一筆,用 rails console 來查看應該還會在,只是更新 deleted_at

# rails console

> drink.last

#<Drink:0x00000001064cf3e0
  id: 17,
  name: "麥香紅茶",
  description: "帶著小麥味的清新紅茶",
  price: 40,
  capacity: 500,
  ingredient: [],
  created_at: Sat, 23 Sep 2023 12:51:36.798989000 UTC +00:00,
  updated_at: Sat, 23 Sep 2023 15:19:49.543071000 UTC +00:00,
  deleted_at: Sat, 23 Sep 2023 15:19:49.542389000 UTC +00:00>] 

如果要真刪除,就用 really_destroy! 方法

  def destroy
    @drink.really_destroy!
    redirect_to drinks_path
  end

我們刪的是最後一筆,用 rails console 來查看應該就不在了

# rails console

> drink.last

Couldn't find Drink with 'id'=2

step 5. 撈資料的方法

如果要撈還沒被刪除過的資料,可以使用 without_deleted

如果要撈全部的資料,可以使用 with_deleted

題外話

由於我們在建立商品的時候,會另外建立 Product 的資料,所以記得也要把他們一起刪除

以上有兩種方式可以完成軟刪除的功能,就看要選哪種

paranoid 還有很多好用的方法,可以參考手冊


上一篇
Day 08 - 用分頁來整理過多的商品
下一篇
Day 10 區分前台與後台
系列文
用 Rails 打造你的電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言