iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Software Development

Rails Active Model系列 第 10

D-10 Active Model 自定義可共用的 validator - 1

  • 分享至 

  • xImage
  •  

說到自定義的 validation,大多數人通常第一時間會想到的是 validate
單數的、沒有 s 的 validate,這個方法可以用來指定物件要在 validation 階段執行某些 method。

而要是專案的 form object 很多,有某些特製的 validation 很常被用到的話,通常會把他搬到抽象層,或是拉出來放在一個 module 裡面,要用再 include。

這邊介紹的是一個可以完全共用的作法,不必弄髒你的抽象層,不必額外 include module,甚至還可以回過頭讓 Active Record 也能夠共用。

那就是使用 ActiveModel::EachValidator 來製作自定義驗證。

class MyValidator < ActiveModel::EachValidator
  def validate_each(form_object, attr, value)
    # 您想做的驗證寫在這邊
  end

  def check_validity!
    # 這個是 EachValidator 提供的 hook method ,會在 initialize 階段觸發
    # 用來檢查其他人傳進來的 options 是否符合規則,如果不合規則,你可以 raise error
  end
end

ActiveModel::EachValidator 提供了 validate_each 這個方法作為進行 validation 時統一使用的介面,並傳入三個 arguments:

  1. 執行 validation 的 object 本體,讓你可以在此 method 裡面往他的 errors 裡塞訊息。
  2. 進行驗證的欄位名稱。
  3. 進行驗證的值。

關於 errors 的使用方式以及 i18n 規劃,之後會講XD。

這樣做有什麼好處呢?又該如何使用呢?我們先講講 validates 這個方法。
當你在 validates 後面加上 options ,假設是

  validates :foo, bar: true

如果這樣設定,那 Active model 背後其實會自動去尋找 BarValidator 這個 class,並且 new 一個實體,代入此行 validation 附帶的設定,存在 class 體內。
這也就是為什麼可以整個專案都通用的原因了。

那使用方式也就很顯而易見了。像是上面定義了 MyValidator,那我就可以這樣做:

  validates :attr, my: true

這樣,ActiveModel 就會自動去使用自定義的 MyValidator 囉~

下一篇來介紹一下,假如跟著這個 key 帶入的 value 不同,有什麼應該注意的地方~


上一篇
D-9 Active Model 擴充功能 - Validation callbacks
下一篇
D-11 Active Model 自定義可共用的 validator - 2
系列文
Rails Active Model28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言