跳到內容 跳到搜尋

Active Model 驗證器

一個簡單的基底類別,可與 ActiveModel::Validations::ClassMethods.validates_with 搭配使用

class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

class MyValidator < ActiveModel::Validator
  def validate(record)
    if some_complex_logic
      record.errors.add(:base, "This record is invalid")
    end
  end

  private
    def some_complex_logic
      # ...
    end
end

任何繼承自 ActiveModel::Validator 的類別都必須實作一個接受 `record` 的方法,稱為 `validate`。

class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

class MyValidator < ActiveModel::Validator
  def validate(record)
    record # => The person instance being validated
    options # => Any non-standard options passed to validates_with
  end
end

若要導致驗證錯誤,您必須直接從驗證訊息中新增至 `record` 的錯誤。

class MyValidator < ActiveModel::Validator
  def validate(record)
    record.errors.add :base, "This is some custom error message"
    record.errors.add :first_name, "This is some complex validation"
    # etc...
  end
end

若要將行為新增至初始化方法,請使用下列簽章

class MyValidator < ActiveModel::Validator
  def initialize(options)
    super
    @my_custom_field = options[:field_name] || :first_name
  end
end

請注意,驗證器只會在整個應用程式生命週期中初始化一次,而不是在每次驗證執行時。

新增自訂驗證器以驗證個別屬性的最簡單方法,是使用方便的 ActiveModel::EachValidator 類別。

class TitleValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
  end
end

現在可以將其與 `validates` 方法結合使用。請參閱 ActiveModel::Validations::ClassMethods#validates 以取得更多相關資訊。

class Person
  include ActiveModel::Validations
  attr_accessor :title

  validates :title, presence: true, title: true
end

在存在前提條件(例如存在 `attr_accessor`)時,存取使用該驗證器的類別會很有用。此類別可在建構函式中透過 `options[:class]` 存取。若要設定驗證器,請覆寫建構函式。

class MyValidator < ActiveModel::Validator
  def initialize(options={})
    super
    options[:class].attr_accessor :custom_attribute
  end
end
方法
K
N
V

屬性

[R] options

類別公開方法

kind()

傳回驗證器的種類。

PresenceValidator.kind   # => :presence
AcceptanceValidator.kind # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 103
def self.kind
  @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
end

new(options = {})

接受可透過 options 讀取器取得的選項。

# File activemodel/lib/active_model/validator.rb, line 108
def initialize(options = {})
  @options = options.except(:class).freeze
end

實例公開方法

kind()

傳回此驗證器的類型。

PresenceValidator.new(attributes: [:username]).kind # => :presence
AcceptanceValidator.new(attributes: [:terms]).kind  # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 116
def kind
  self.class.kind
end

validate(record)

在子類別中覆寫此方法,並加入驗證邏輯,視需要將錯誤加入記錄的 errors 陣列。

# File activemodel/lib/active_model/validator.rb, line 122
def validate(record)
  raise NotImplementedError, "Subclasses must implement a validate(record) method."
end