iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
自我挑戰組

Ruby on Rails JS系列 第 27

Ruby on Rails Model 驗證及回呼

資料驗證(Validation)
回呼(Callback)
資料驗證(Validation)
開發網站應⽤程式,資料的正確性是很重要的。⼤家應該都不會想被有意或無意的
在資料庫裡塞了奇怪的資料,所以通常都會加上資料驗證的機制,確保寫入的資料
是符合規定的。
驗證該在哪裡做?
那,這個資料驗證機制該寫在哪裡比較好呢?常⾒的選項有:

  1. 前端驗證:在 HTML ⾴⾯使⽤ JavaScript 在使⽤者填寫資料的時候檢查。
  2. 後端驗證:資料上傳到伺服器後,在寫入資料庫之前由網站應⽤程式進⾏檢
    查。
  3. 資料庫驗證:直接由資料庫本⾝所提供的功能來做資料驗證。
    雖然前端驗證簡單容易做,但如果如果使⽤者關掉 JavaScript 功能,或是直接檢視
    HTML 原始碼,⾃⼰做⼀個⼀樣的表單,⼀樣可以送資料進來,所以即使在 HTML
    ⾴⾯已經有驗證,在寫入資料庫前還是得再做⼀次檢查。
    資料庫驗證雖然可⾏,但缺點不⾒得每種資料庫系統都有提供⼀樣的功能,⼀旦換
    了資料庫系統可能會沒辦法正常運作。但好處是如果這個資料庫還有跟其它程式語
    ⾔開發的系統共⽤,資料庫驗證比較可以確保不管是哪個系統寫進來的資料都是正
    確的了。
    資料驗證這件事在 Rails 的 MVC 三分天下的架構中,Controller 跟 Model 都可以做
    這件事,要在 View 裡寫 JavaScript 做檢查也可以,但這件事如果交給 Controller 或
    View 來做,⼀來會讓程式碼的邏輯變得更複雜,⼆來這個驗證不容易被重複使⽤,
    也不容易被測試,所以資料機制寫在 Model 裡是比較合理⽽且單純的。
    在 Model 裡加上驗證
    19 Model 驗證及回呼
    288
    假設我們有⼀個叫做 Article 的 Model,希望每篇⽂章的⽂章標題(title)是必填
    資訊,可以這樣寫:
class Article < ApplicationRecord
validates :title, presence: true
end

中間那⾏ validates ⽅法的意思是「title 這個欄位為必填欄位」,讓我們開
rails console 起來試⼀下:

$ bin/rails console
>> a1 = Article.new
=> #<Article id: nil, title: nil, content: nil, is_online: nil, c
reated_at: nil, updated_at: nil, photo: nil, user_id: nil>

先⽤ new ⽅法建立⼀個 Article 物件,然後⽤ errors ⽅法看⼀下這個物件有沒
有什麼狀況:

>> a1.errors.any?
=> false
這時候看起來沒什麼問題。接著試著呼叫 save ⽅法把這顆物件存入資料表:
>> a1.save
(0.2ms) begin transaction
(0.1ms) rollback transaction
=> false
發現 save ⽅法失敗了,並且回傳 false,來看看到底是哪邊有問題:
>> a1.errors.any?
=> true

原本沒問題的,在 save 之後變得有問題了。來看看錯誤訊息是什麼:

>> a1.errors.full_messages
=> ["Title can't be blank"]

除了 validates :title, presence: true 之外,還有另⼀種寫法:

class Article < ActiveRecord::Base
validates_presence_of :title
end

效果也是⼀樣的。
除了 presence 之外,Rails 還有提供其它像是 uniqueness 、 length 或
numericality 等便利的驗證器,使⽤⽅法可直接參考 Rails Guide 的 Validations
章節。

參考資料

[為你自己學Ruby on Rails]https://railsbook.tw/chapters/08-ruby-basic-4.html


上一篇
Ruby on Rails View Helper
下一篇
Ruby on Rails Model 驗證及回呼
系列文
Ruby on Rails JS29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言