關於Validation的方法使用

2023-04-20 15:01:25

acceptance驗證

acceptance 是 Rails 中的一個驗證器(validator),用於驗證一個布林型別的屬性是否被接受。在表單中,通常會有一些核取方塊或無線電鈕,使用者需要勾選或選擇才能提交表單。acceptance 驗證器用於確保這些核取方塊或無線電鈕已經被選中或勾選。

當一個屬性被驗證時,acceptance 驗證器會檢查該屬性是否為 true。如果為 true,則驗證通過;否則,驗證失敗,並將錯誤資訊新增到模型物件的 errors 集合中。

例如,在下面的程式碼中,acceptance 驗證器用於驗證 terms_of_service 屬性是否被接受:

class Person < ApplicationRecord
  validates :terms_of_service, acceptance: true
end

在這個例子中,如果一個 Person 物件的 terms_of_service 屬性沒有被設定為 true,那麼該物件就無法通過驗證,並且會在 errors 集合中新增一個名為 terms_of_service 的錯誤資訊。

在表單中,可以使用 Rails 提供的 check_boxradio_button 輔助方法來生成核取方塊或無線電鈕,並自動新增 acceptance 驗證器。例如:

<%= form_for @person do |f| %>
  <%= f.label :terms_of_service do %>
    <%= f.check_box :terms_of_service %>
    I agree to the terms of service
  <% end %>
<% end %>

這個表單會生成一個名為 terms_of_service 的核取方塊,並自動將其關聯到 Person 模型類的 terms_of_service 屬性。當用戶提交表單時,如果核取方塊被選中,那麼該屬性會被設定為 true,並且表單資料就可以被提交。如果核取方塊沒有被選中,那麼表單資料無法通過驗證,並且會顯示一個名為 terms_of_service 的錯誤資訊。

validates_associated

當您的模型與其他模型有關聯,並且它們也需要驗證時,您應該使用這個幫助器。當你試圖儲存物件時,有效嗎?將在每個相關物件上呼叫。

class Library < ApplicationRecord
  has_many :books
  validates_associated :books
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Library 的類,並建立了與 Book 模型類的關聯關係。它使用了 has_many 方法來指定一個圖書館可以擁有多本書,並使用了 validates_associated 方法來確保與該模型關聯的書籍資料也是有效的。

has_many 方法用於在模型類之間建立一對多的關聯關係。在這個例子中,Library 模型類通過 has_many :books 方法指定一個圖書館可以擁有多本書。這個方法會自動為 Library 類生成一個名為 books 的實體方法,該方法用於返回與該圖書館相關聯的所有書籍的集合。同時,它還會自動為 Book 類生成一個名為 library 的實體方法,該方法用於返回與該書籍相關聯的圖書館物件。

validates_associated 方法用於驗證與該模型類關聯的其他模型類的資料是否有效。在這個例子中,validates_associated :books 方法用於驗證與 Library 模型類關聯的所有書籍資料是否有效。如果任何一本書籍的資料無效,那麼整個圖書館物件都無法通過驗證,並且會在模型物件的 errors 集合中新增一個名為 books 的錯誤資訊。

需要注意的是,validates_associated 方法只驗證與該模型類關聯的其他模型類的資料是否有效,而不會驗證該模型類本身的資料是否有效。因此,如果需要同時驗證該模型類本身的資料和與其關聯的其他模型類的資料,還需要使用其他的驗證器來實現。

confirmation確認

class Person < ApplicationRecord
  validates :email, confirmation: true
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的 email 屬性進行驗證。

在這個例子中,validates 方法用於為 email 屬性新增驗證規則。具體來說,使用了 confirmation 選項,表示需要對 email 屬性進行確認驗證。這意味著在表單中提交時,除了輸入 email 屬性的值之外,還需要再次輸入相同的值,以便驗證兩次輸入的值是否一致。如果兩次輸入的值不一致,則會在模型物件的 errors 集合中新增一個名為 email_confirmation 的錯誤資訊。

需要注意的是,confirmation 驗證器只適用於需要確認的屬性,例如密碼和電子郵件地址等。如果要對其他型別的屬性進行驗證,可以使用其他的驗證器來實現。

class Person < ApplicationRecord
  validates :email, confirmation: true
  validates :email_confirmation, presence: true
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的 email 屬性進行驗證。

在這個例子中,validates 方法用於為 email 屬性新增驗證規則。具體來說,使用了 confirmation 選項,表示需要對 email 屬性進行確認驗證。這意味著在表單中提交時,除了輸入 email 屬性的值之外,還需要再次輸入相同的值,以便驗證兩次輸入的值是否一致。如果兩次輸入的值不一致,則會在模型物件的 errors 集合中新增一個名為 email_confirmation 的錯誤資訊。

在這個例子中,還新增了另一個驗證規則,用於驗證 email_confirmation 屬性的存在性。這是因為在進行 email 屬性的確認驗證時,需要通過表單中的 email_confirmation 屬性來獲取確認電子郵件地址的值。因此,如果 email_confirmation 屬性不存在或為空,確認驗證將無法進行,因此需要驗證其存在性。

需要注意的是,confirmation 驗證器只適用於需要確認的屬性,例如密碼和電子郵件地址等。如果要對其他型別的屬性進行驗證,可以使用其他的驗證器來實現。

驗證大小寫

class Person < ApplicationRecord
  validates :email, confirmation: { case_sensitive: false }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的 email 屬性進行驗證。

在這個例子中,validates 方法用於為 email 屬性新增驗證規則。具體來說,使用了 confirmation 選項,並傳遞了一個名為 case_sensitive 的雜湊引數,將其設定為 false。這意味著在進行電子郵件地址確認驗證時,將忽略電子郵件地址的大小寫。例如,如果 email 屬性的值為 "[email protected]",則確認驗證器會接受 "[email protected]" 或其他任何大小寫組合的電子郵件地址作為有效值。

需要注意的是,confirmation 驗證器只適用於需要確認的屬性,例如密碼和電子郵件地址等。如果要對其他型別的屬性進行驗證,可以使用其他的驗證器來實現。

comparison比較

class Promotion < ApplicationRecord
  validates :start_date, comparison: { greater_than: :end_date }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Promotion 的類,並對其中的 start_date 屬性進行驗證。

在這個例子中,validates 方法用於為 start_date 屬性新增驗證規則。具體來說,使用了 comparison 選項,並傳遞了一個名為 greater_than 的雜湊引數,將其設定為 end_date。這意味著要驗證 start_date 屬性的值是否大於 end_date 屬性的值。

需要注意的是,comparison 驗證器是 Rails 6 中引入的新特性,在 Rails 5 中不存在。它用於比較兩個屬性的值,並驗證它們之間的關係,包括大於、小於、大於等於、小於等於等關係。在本例中,使用了 greater_than 選項,表示要驗證 start_date 屬性的值是否大於 end_date 屬性的值。

在實際使用中,可以在表單中新增名為 start_dateend_date 的日期選擇器,用於輸入促銷活動的開始日期和結束日期。例如:

<%= form_for @promotion do |f| %>
  <%= f.label :start_date %>
  <%= f.date_field :start_date %>

  <%= f.label :end_date %>
  <%= f.date_field :end_date %>

  <%= f.submit "Save" %>
<% end %>

這個表單會生成名為 start_dateend_date 的日期選擇器,用於輸入促銷活動的開始日期和結束日期。當用戶提交表單時,它會驗證 start_date 屬性的值是否大於 end_date 屬性的值,並將模型物件儲存到資料庫中。如果 start_date 屬性的值小於或等於 end_date 屬性的值,則會顯示一個名為 start_date 的錯誤資訊。

這些是 Active Record 驗證器 comparison 選項中可用的比較運運算元及其預設錯誤訊息:

  • :greater_than - 指定值必須大於提供的值。該選項的預設錯誤訊息為 "必須大於 %{count}"。
  • :greater_than_or_equal_to - 指定值必須大於或等於提供的值。該選項的預設錯誤訊息為 "必須大於或等於 %{count}"。
  • :equal_to - 指定值必須等於提供的值。該選項的預設錯誤訊息為 "必須等於 %{count}"。
  • :less_than - 指定值必須小於提供的值。該選項的預設錯誤訊息為 "必須小於 %{count}"。
  • :less_than_or_equal_to - 指定值必須小於或等於提供的值。該選項的預設錯誤訊息為 "必須小於或等於 %{count}"。
  • :other_than - 指定值必須不等於提供的值。該選項的預設錯誤訊息為 "必須不等於 %{count}"。

這些選項可以用於在 Active Record 模型中驗證屬性的值是否符合指定的比較運運算元。例如,可以使用 :greater_than 選項來驗證某個屬性的值必須大於指定的值:

validates :some_attribute, comparison: { greater_than: 10 }

這會在模型物件上新增一個驗證規則,以確保 some_attribute 屬性的值大於 10。如果該屬性的值小於或等於 10,則會在模型物件的 errors 集合中新增一個錯誤訊息,該訊息的內容為 "must be greater than 10"。如果需要自定義錯誤訊息,可以在 validates 方法中使用 message 選項來指定它,例如:

validates :some_attribute, comparison: { greater_than: 10, message: "must be greater than 10!" }

這會在模型物件上新增一個驗證規則,以確保 some_attribute 屬性的值大於 10。如果該屬性的值小於或等於 10,則會在模型物件的 errors 集合中新增一個錯誤訊息,該訊息的內容為 "must be greater than 10!"。

exclusion排除

class Account < ApplicationRecord
  validates :subdomain, exclusion: { in: %w(www us ca jp),
    message: "%{value} is reserved." }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Account 的類,並對其中的 subdomain 屬性進行驗證。

在這個例子中,validates 方法用於為 subdomain 屬性新增驗證規則。具體來說,使用了 exclusion 選項,並傳遞了一個雜湊引數,將其設定為 in 選項為 ["www", "us", "ca", "jp"]。這意味著要驗證 subdomain 屬性的值是否不在這個陣列中。

如果 subdomain 屬性的值在指定的陣列中,將會在模型物件的 errors 集合中新增一個錯誤訊息,該訊息的內容為 "%{value} is reserved.",其中 %{value} 會被替換為實際的屬性值。

在實際使用中,這個驗證器可以用於確保使用者輸入的 subdomain 屬性值不是某些預留的關鍵字,例如在一個多租戶的應用程式中,可能需要保留一些子域名用於系統的內部使用,而不允許使用者建立這些子域名。例如:

validates :subdomain, exclusion: { in: %w(www us ca jp),
  message: "%{value} is reserved for internal use." }

這個驗證器會在使用者提交表單時驗證 subdomain 屬性,並確保其值不在 ["www", "us", "ca", "jp"] 陣列中。如果 subdomain 屬性的值在指定的陣列中,將會顯示一個錯誤訊息,該訊息的內容為 "%{value} is reserved for internal use."。如果需要自定義錯誤訊息,可以在 validates 方法中使用 message 選項來指定它。

format格式

class Product < ApplicationRecord
  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
    message: "only allows letters" }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Product 的類,並對其中的 legacy_code 屬性進行驗證。

在這個例子中,validates 方法用於為 legacy_code 屬性新增驗證規則。具體來說,使用了 format 選項,並傳遞了一個雜湊引數,將其設定為 with 選項為 /\A[a-zA-Z]+\z/。這意味著要驗證 legacy_code 屬性的值是否只包含字母,且不包含空格、數位或其他字元。

如果 legacy_code 屬性的值不符合指定的正規表示式,則會在模型物件的 errors 集合中新增一個錯誤訊息,該訊息的內容為 "only allows letters"。

在實際使用中,這個驗證器可以用於確保使用者輸入的 legacy_code 屬性值只包含字母,例如在一個產品管理系統中,可能需要保證產品的程式碼是由字母組成的,而不允許包含其他字元。例如:

validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
  message: "only allows letters and no other characters or spaces" }

這個驗證器會在使用者提交表單時驗證 legacy_code 屬性,並確保其值只包含字母。如果 legacy_code 屬性的值包含非字母字元,則會顯示一個錯誤訊息,該訊息的內容為 "only allows letters and no other characters or spaces"。如果需要自定義錯誤訊息,可以在 validates 方法中使用 message 選項來指定它。

inclusion包含

class Coffee < ApplicationRecord
  validates :size, inclusion: { in: %w(small medium large),
    message: "%{value} is not a valid size" }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Coffee 的類,並對其中的 size 屬性進行驗證。

在這個例子中,validates 方法用於為 size 屬性新增驗證規則。具體來說,使用了 inclusion 選項,並傳遞了一個雜湊引數,將其設定為 in 選項為 ["small", "medium", "large"]。這意味著要驗證 size 屬性的值是否在指定的陣列中。

如果 size 屬性的值不在指定的陣列中,則會在模型物件的 errors 集合中新增一個錯誤訊息,該訊息的內容為 "%{value} is not a valid size",其中 %{value} 會被替換為實際的屬性值。

在實際使用中,這個驗證器可以用於確保使用者輸入的 size 屬性值是預定義的值之一,例如在一個咖啡店管理系統中,可能需要確保咖啡杯的大小是預定義的幾種規格之一,而不允許使用者輸入其他值。例如:

validates :size, inclusion: { in: %w(small medium large),
  message: "%{value} is not a valid cup size. Please choose small, medium or large." }

這個驗證器會在使用者提交表單時驗證 size 屬性,並確保其值是 ["small", "medium", "large"] 陣列中的一項。如果 size 屬性的值不在指定的陣列中,則會顯示一個錯誤訊息,該訊息的內容為 "%{value} is not a valid cup size. Please choose small, medium or large."。如果需要自定義錯誤訊息,可以在 validates 方法中使用 message 選項來指定它。

length

class Person < ApplicationRecord
  validates :name, length: { minimum: 2 }
  validates :bio, length: { maximum: 500 }
  validates :password, length: { in: 6..20 }
  validates :registration_number, length: { is: 6 }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的幾個屬性進行驗證。

在這個例子中,validates 方法用於為 namebiopasswordregistration_number 屬性新增驗證規則。具體來說:

  • validates :name, length: { minimum: 2 } 表示要驗證 name 屬性的長度是否至少為 2 個字元。
  • validates :bio, length: { maximum: 500 } 表示要驗證 bio 屬性的長度是否不超過 500 個字元。
  • validates :password, length: { in: 6..20 } 表示要驗證 password 屬性的長度是否在 6 到 20 個字元之間。
  • validates :registration_number, length: { is: 6 } 表示要驗證 registration_number 屬性的長度是否恰好為 6 個字元。

如果任何一個屬性的值不符合指定的長度要求,則會在模型物件的 errors 集合中新增一個錯誤訊息。

在實際使用中,這些驗證器可以用於確保使用者輸入的屬性值符合預期的長度要求。例如,name 屬性可能需要至少包含兩個字元,以確保姓名的有效性。bio 屬性可能需要限制在 500 個字元以內,以確保使用者不會輸入過長的自我介紹。password 屬性可能需要在安全性和易用性之間找到平衡,因此長度可能需要在一定範圍內。registration_number 屬性可能需要確保長度恰好為 6 個字元,以確保準確性。

需要注意的是,這些驗證器只是驗證屬性的長度,而不是內容。如果需要對屬性的內容進行驗證,可以使用其他型別的驗證器,例如 presenceformat 等。

預設錯誤訊息取決於正在執行的長度驗證的型別。您可以使用:wrong_length、:too_long和:too_short選項客製化這些訊息,並使用%{count}作為與所使用的長度約束相對應的數位的預留位置。您仍然可以使用:message選項來指定錯誤訊息

class Person < ApplicationRecord
  validates :bio, length: { maximum: 1000,
    too_long: "%{count} characters is the maximum allowed" }
end

numericality數值

class Player < ApplicationRecord
  validates :points, numericality: true
  validates :games_played, numericality: { only_integer: true }
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Player 的類,並對其中的 pointsgames_played 屬性進行驗證。

在這個例子中,validates 方法用於為 points 屬性新增一個驗證規則。具體來說,使用了 numericality 選項,表示要驗證屬性的值是否為數值型別。這個驗證器將確保 points 屬性的值包含一個有效的數值。例如,如果 points 的值為 "123" 或 "123.45",則驗證將通過,但如果 points 的值為 "abc" 或 "123abc",則驗證將失敗。

在第二個驗證器中,同時通過了 numericalityonly_integer 選項,表示要驗證 games_played 屬性的值是否為整數型別。這個驗證器將確保 games_played 屬性的值為一個整數。例如,如果 games_played 的值為 "123",則驗證將通過,但如果 games_played 的值為 "123.45" 或 "abc",則驗證將失敗。

需要注意的是,這些驗證器只是驗證屬性的值是否為數值型別或整數型別,而不是具體的值是否符合特定的條件。如果需要對屬性的值進一步驗證,可以使用其他型別的驗證器,例如 inclusionexclusionlengthformat 等。

在實際應用中,這些驗證器可以用於確保 Player 物件的 pointsgames_played 屬性包含有效的數值或整數型別的值。如果驗證失敗,則會在模型物件的 errors 集合中新增一個錯誤訊息。這個錯誤訊息的預設內容為 "is not a number" 或 "must be an integer",具體內容取決於驗證器的選項。如果需要自定義錯誤訊息,可以像我在之前的回答中所述那樣使用 message 選項。

這些選項是用於 numericality 驗證器的子選項,用於進一步驗證屬性的值是否符合特定的條件,具體說明如下:

  1. greater_than - 指定屬性的值必須大於指定的值。預設錯誤訊息為 "must be greater than %{count}"。
  2. greater_than_or_equal_to - 指定屬性的值必須大於或等於指定的值。預設錯誤訊息為 "must be greater than or equal to %{count}"。
  3. equal_to - 指定屬性的值必須等於指定的值。預設錯誤訊息為 "must be equal to %{count}"。
  4. less_than - 指定屬性的值必須小於指定的值。預設錯誤訊息為 "must be less than %{count}"。
  5. less_than_or_equal_to - 指定屬性的值必須小於或等於指定的值。預設錯誤訊息為 "must be less than or equal to %{count}"。
  6. other_than - 指定屬性的值必須不等於指定的值。預設錯誤訊息為 "must be other than %{count}"。
  7. in - 指定屬性的值必須在指定的範圍內。預設錯誤訊息為 "must be in %{count}"。
  8. odd - 如果設定為 true,則指定屬性的值必須是奇數。預設錯誤訊息為 "must be odd"。
  9. even - 如果設定為 true,則指定屬性的值必須是偶數。預設錯誤訊息為 "must be even"。

這些選項可以與其他驗證器組合使用,以進一步驗證屬性的值是否符合特定的條件,並提供自定義錯誤訊息。例如,可以使用以下驗證器驗證屬性的值是否為正數:

validates :number, numericality: { greater_than: 0, message: "must be a positive number" }

如果屬性的值不是正數,則會在模型物件的 errors 集合中新增一個錯誤訊息,內容為 "must be a positive number"。這樣可以幫助開發者更好地控制資料的有效性,提高應用程式的穩定性和可靠性。

presence驗證為空

class Person < ApplicationRecord
  validates :name, :login, :email, presence: true
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的 nameloginemail 屬性進行驗證。

在這個例子中,validates 方法用於為 nameloginemail 屬性新增一個驗證規則。具體來說,使用了 presence 選項,表示要驗證屬性的值是否存在,即不能為空值或空字串。這個驗證器將確保 nameloginemail 屬性的值都不為空。如果其中任何一個屬性的值為空,則驗證將失敗。

需要注意的是,presence 驗證器只是驗證屬性的值是否存在,而不是具體的值是否符合特定的條件。如果需要對屬性的值進一步驗證,可以使用其他型別的驗證器,例如 lengthformatinclusionexclusion 等。

在實際應用中,這些驗證器可以用於確保 Person 物件的 nameloginemail 屬性都不為空。如果驗證失敗,則會在模型物件的 errors 集合中新增一個錯誤訊息。這個錯誤訊息的預設內容為 "can't be blank",表示屬性的值不能為空。如果需要自定義錯誤訊息,可以像我在之前的回答中所述那樣使用 message 選項。

absence

class Person < ApplicationRecord
  validates :name, :login, :email, absence: true
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Person 的類,並對其中的 nameloginemail 屬性進行驗證。

在這個例子中,validates 方法用於為 nameloginemail 屬性新增一個驗證規則。具體來說,使用了 absence 選項,表示要驗證屬性的值是否不存在,即必須為 nil 或空字串。這個驗證器將確保 nameloginemail 屬性的值都不存在。如果其中任何一個屬性的值不為空,則驗證將失敗。

需要注意的是,absence 驗證器與 presence 驗證器相反。presence 驗證器用於驗證屬性的值是否存在,而absence 驗證器用於驗證屬性的值是否不存在。這兩個驗證器都是用於確保屬性的值符合預期,並且避免了資料不一致的情況。

在實際應用中,這些驗證器可以用於確保 Person 物件的 nameloginemail 屬性都不存在。如果驗證失敗,則會在模型物件的 errors 集合中新增一個錯誤訊息。這個錯誤訊息的預設內容為 "must be blank",表示屬性的值必須為空。如果需要自定義錯誤訊息,可以像我在之前的回答中所述那樣使用 message 選項。

uniqueness唯一性

class Account < ApplicationRecord
  validates :email, uniqueness: true
end

這段程式碼是一個 Rails 應用程式中的 ActiveRecord 模型類,它用於定義一個名為 Account 的類,並對其中的 email 屬性進行驗證。

在這個例子中,validates 方法用於為 email 屬性新增一個驗證規則。具體來說,使用了 uniqueness 選項,表示要驗證屬性的值是否唯一。這個驗證器將確保 email 屬性的值在整個 Account 表中都是唯一的。如果有多個 Account 物件具有相同的 email 屬性值,則驗證將失敗。

需要注意的是,uniqueness 驗證器用於確保屬性的值在整個表中是唯一的,它不會驗證屬性的值是否存在。如果需要同時驗證屬性的存在性,可以在驗證器鏈中使用 presence 驗證器。

在實際應用中,這個驗證器可以用於確保 Account 物件的 email 屬性是唯一的。如果驗證失敗,則會在模型物件的 errors 集合中新增一個錯誤訊息。這個錯誤訊息的預設內容為 "has already been taken",表示屬性的值已經被佔用了。如果需要自定義錯誤訊息,可以像我在之前的回答中所述那樣使用 message 選項。

validates_with自定義驗證器

validates_with 是 ActiveRecord 模型類中的一個方法,它用於將自定義驗證器新增到模型類中,以驗證模型物件的屬性。

使用 validates_with 方法可以將自定義驗證器新增到模型類中,例如:

class Person < ApplicationRecord
  validates_with GoodnessValidator
end

在這個例子中,我們將 GoodnessValidator 自定義驗證器新增到 Person 模型類中。當我們在建立或更新 Person 物件時,GoodnessValidator 將會被呼叫,以驗證 Person 物件的屬性。

需要注意的是,validates_with 方法和其他內建驗證方法(如 validates_presence_ofvalidates_uniqueness_of 等)有所不同,它不會自動新增錯誤訊息到模型物件的 errors 集合中。相反,自定義驗證器需要自行處理錯誤訊息的新增。

在自定義驗證器的 validate 方法中,我們可以使用 record.errors.add 方法將錯誤訊息新增到模型物件的 errors 集合中。例如:

class GoodnessValidator < ActiveModel::Validator
  def validate(record)
    if record.first_name == "Evil"
      record.errors.add :base, "This person is evil"
    end
  end
end

在這個範例中,如果 Person 物件的 first_name 屬性為 "Evil",則會在模型物件的 errors 集合中新增一個錯誤訊息,指示此人是邪惡的。

因此,使用 validates_with 方法需要自定義驗證器開發人員具備一定的 Ruby 程式設計知識和技能,以確保驗證器能夠正確地處理錯誤訊息的新增和其他驗證邏輯。

validates_each

class Person < ApplicationRecord
  validates_each :name, :surname do |record, attr, value|
    record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
  end
end

這段程式碼定義了一個 Person 模型類,並使用 validates_each 方法為 namesurname 兩個屬性新增了一個自定義驗證器。

validates_each 方法是一個 Rails 提供的方法,它允許我們為指定的屬性新增自定義驗證器程式碼塊。在這個例子中,我們使用了 validates_each 方法並傳入兩個引數 namesurname,這意味著我們將為這兩個屬性新增自定義驗證器。

自定義驗證器程式碼塊中的第一個引數 record 是當前正在驗證的模型物件。第二個引數 attr 是當前正在驗證的屬性名稱,第三個引數 value 是當前屬性的值。

在這個例子中,我們使用了一個正規表示式 /\A[[:lower:]]/ 來檢查屬性值是否以小寫字母開頭。如果是,我們就在模型物件的 errors 陣列中新增一個錯誤訊息,以通知使用者該屬性必須以大寫字母開頭。

需要注意的是,使用 validates_each 方法允許我們為屬性新增更加複雜的自定義驗證邏輯,而不僅僅是簡單的比較或格式驗證。然而,需要注意的是,由於自定義驗證器是在每次驗證時被呼叫的,因此如果驗證邏輯較為複雜,它可能會對效能產生一定的影響。