Posted at

Sequel Model Validation

More than 3 years have passed since last update.

http://sequel.jeremyevans.net/rdoc/files/doc/validations_rdoc.html の要約

内容の理解が進み次第追記します。


Validationの使い方

Validation内容は validate メソッドに実装する。

オブジェクトに対して valid? を呼び出すことでValidationをパスするか判断できる。

Validationをパスしない状態で save が呼ばれると Sequel::ValidationFailed エラーが発生する。

エラーを発生させたくない場合は raise_on_save_failure にfalseを設定すれば良い。

class Album < Sequel::Model

def validate
super
errors.add(:name, 'cannot be empty') if !name || name.empty?
end
end

Album.new.valid? # false
Album.new(:name=>'').valid? # false
Album.new(:name=>'RF').valid? # true

valid? がfalseを返した場合、 errors メソッドでエラー内容を取得できる。

errorsvalid? が呼ばれるまではセットされない。

a = Album.new

# => #<Album @values={}>
a.valid?
# => false
a.errors
# => {:name=>["cannot be empty"]}

# 下記はダメな例
Album.new.errors
# => {}


Validationが行われる場合と行われない場合

最終的に save が呼ばれる場合、validate メソッドが呼び出される。

例えば create は内部的に save を呼び出している。

insertsave を経由しないためvalidationは行われない

save に対して :validate => false をつけて呼び出すとValidationはスキップされる。


validation_helpers

Validationを簡単に書けるようにするヘルパーメソッドが定義されている。

class Album < Sequel::Model

def validate
super
errors.add(:name, 'cannot be empty') if !name || name.empty?
errors.add(:name, 'is already taken') if name && new? && Album[:name=>name]
errors.add(:website, 'cannot be empty') if !website || website.empty?
errors.add(:website, 'is not a valid URL') unless website =~ /\Ahttps?:\/\//
end
end

上記は validation_helpersを使って下記のように書き換えられる。

class Album < Sequel::Model

plugin :validation_helpers
def validate
super
validates_presence [:name, :website]
validates_unique :name
validates_format /\Ahttps?:\/\//, :website, :message=>'is not a valid URL'
end
end


validates_presence, validates_not_null

validates_presence はNULL, nil, 空文字列じゃないなんらかの値が入っている。

またはempty?、blank?でfalseが返って来る値が入っている。

validates_not_null はNULL, nilではないかだけ確認する。空文字列でもOK

class Album < Sequel::Model

def validate
super
validates_presence [:name, :website, :debut_album]
end
end


validates_format

与えられる正規表現を満足するかどうか。文字列が所定のフォーマットにのっとっているか確認できる。

class Album < Sequel::Model

def validate
super
validates_format /\A\d\d\d-\d-\d{7}-\d-\d\z/, :isbn
validates_format /\a[0-9a-zA-Z:' ]+\z/, :name
end
end


validates_exact_length, validates_min_length, validates_max_length, validates_length_range

文字列長の一致、下限、上限、範囲を確認できる。

class Album < Sequel::Model

def validate
super
validates_exact_length 17, :isbn
validates_min_length 3, :name
validates_max_length 100, :name
validates_length_range 3..100, :name
end
end


validates_integer, validates_numeric

整数かどうかと、数値かどうかを確認できる。

class Album < Sequel::Model

def validate
super
validates_integer :copies_sold
validates_numeric :replaygain
end
end


validates_includes

取りうる値の候補を配列で指定する。

class Album < Sequel::Model

def validate
validates_includes [1, 2, 3, 4, 5], :rating
end
end


validates_type

所定のクラスのオブジェクトかどうか確認する。

class Album < Sequel::Model

def validate
super
validates_type String, [:name, :website]
validates_type :Artist, :artist
validates_type [String, Integer], :foo
end
end


validates_schema_types

ざっと読んだけどよくわからず、後で追記するかも。原文参照のこと。


validates_unique

値がユニークか否か・・・ なんだけど使い方が他のhelperと異なるので原文を参照した方が良い。