當資料寫進資料庫時,需要確保存進來的資料是有效的,你應該不會想要資料庫被塞一些奇怪的資料進來吧!舉例來說,使用者需填入有效的 Email 格式,這就是需要資料驗證的地方。
資料驗證要寫在哪呢?比較常見的選項有:
前端驗證簡單且容易做,但有人關掉 JavaScript ,或是直接檢視 HTML 原始碼,並做一樣的表單,一樣可以寫進資料庫,所以這個不推薦。
資料庫驗證一樣可以做驗證,但是每一個資料庫系統所提供的功能不一定一樣,所以當你換一個資料庫可能會沒辦法正常運行。
後端驗證在 Rails 中 MVC 架構,M 跟 C 可以來做這件事,但是在 Controller 驗證,會使其看起來較為複雜,我們盡量保持 Controller 輕巧短小;所以資料驗證寫在 Model 層是較為合理的且單純的。
補充:
在學習 Rails 的過程中常聽到 "Skinny Controller, Fat Model" 一詞;在開發網站的過程中,常常被告誡商業邏輯要寫在 Model 中而不是 Controller ,這樣的做法會讓商業邏輯更好測試且可以被重複利用,Controller 就做好 View 與 Model 資料交換的角色就好了。
下面介紹一些常用的驗證!
現在我們有 Owner
的 Model 裡面有 name
欄位,我想要這個欄位是必填資訊,所以我們可以這樣寫:
# owner.rb
class Owner < ApplicationRecord
validates :name , presence: true
end
# 另一種寫法
class Owner < ApplicationRecord
validates_presence_of :name
end
這樣我們就完成驗證的條件了,我們到 rails console
建立一個 Owner4 物件:
>> owner4 = Owner.new
=> #<Owner id: nil, name: nil, tel: nil, created_at: nil, updated_at: nil>
我們先看他有沒有什麼錯誤:
owner4.errors.any?
=> false
那我們將它存進資料庫吧!
>> owner4.save
=> false
存入失敗,我們再看有什麼問題:
>> owner4.errors.any?
=> true
>> owner4.errors.full_messages
=> ["Name can't be blank"]
因為有驗證的原因,所以當我 name
欄位沒寫東西,它就不讓我存進資料庫。
當不希望資料庫有一模一樣的名字,我們可以用 uniqueness
來驗證資料庫是否有相同的資料:
# owner.rb
class Owner < ApplicationRecord
validates :name , uniqueness: true
end
在學驗證時,常常會以爲只有用 save
跟 create
寫入資料庫時才會有驗證錯誤的問題發生,但其實不用寫入資料庫也可以知道這筆資料是否有效。
我們先看目前資料庫有哪些資料:
>> Owner.all
=> #<ActiveRecord::Relation [#<Owner id: 1, name: "春春", tel: nil, created_at: "2022-10-13 06:02:43.505023000 +0000", updated_at: "2022-10-13 06:02:43.505023000 +0000">, #<Owner id: 2, name: "阿肥", tel: nil, created_at: "2022-10-13 06:02:48.212935000 +0000", updated_at: "2022-10-13 06:02:48.212935000 +0000">, #<Owner id: 3, name: "酷酷", tel: nil, created_at: "2022-10-14 06:05:38.616165000 +0000", updated_at: "2022-10-14 06:10:34.652542000 +0000">]>
這邊可以看到第一筆資料有 name: "春春"
,那我們故意新增一筆同名的資料:
owner4 = Owner4.new(name: "春春")
看一下有沒有問題:
>> owner4.errors.any?
=> false
沒有問題,接著我們看可不可以通過驗證:
>> owner4.valids?
=> false
沒通過驗證,為什麼?!看一下錯誤訊息:
>> owner4.errors.full_messages
=> ["Name has already been taken"]
這邊有兩個觀念:
save
也是會觸發驗證。以上介紹兩種基本的兩種驗證方式,更多驗證模式可以去 Rails Guides 查看。
參考資料: