General
Lutaml::Model provides comprehensive validation for data models using the validate and validate! methods.
-
The
validatemethod returns anerrorsarray containing all validation errors. This method is used for checking the validity of the model silently. -
The
validate!method raises aLutaml::Model::ValidationErrorthat contains all the validation errors. This method is used for forceful validation of the model through raising an error.
Validation types
Lutaml::Model supports the following validation types:
Collection validation
The collection option validates collection size ranges.
attribute :items, :string, collection: (1..) # At least one item
attribute :tags, :string, collection: (0..5) # Up to 5 tagsValue enumeration validation
The values option validates that an attribute value is one of a fixed set of values.
attribute :status, :string, values: %w[draft published archived]Choice validation
The choice directive validates that attributes within a defined range are present.
choice(min: 1, max: 2) do
attribute :email, :string
attribute :phone, :string
endValidation examples
The following class will validate the name is present and degree_settings attributes to ensure that it has at least one element and that the description attribute is one of the values in the set [one, two, three].
class Klin < Lutaml::Model::Serializable
attribute :name, :string, required: true
attribute :degree_settings, :integer, collection: (1..)
attribute :description, :string, values: %w[one two three]
attribute :id, :integer
attribute :age, :integer
choice(min: 1, max: 1) do
choice(min: 1, max: 2) do
attribute :prefix, :string
attribute :forename, :string
end
attribute :nick_name, :string
end
xml do
map_element 'name', to: :name
map_attribute 'degree_settings', to: :degree_settings
end
end
klin = Klin.new(name: "Klin", degree_settings: [100, 200, 300], description: "one", prefix: "Ben")
klin.validate
# => []
klin = Klin.new(name: "Klin", degree_settings: [], description: "four", prefix: "Ben", nick_name: "Smith")
klin.validate
# => [
# #<Lutaml::Model::CollectionSizeError: degree_settings must have at least 1 element>,
# #<Lutaml::Model::ValueError: description must be one of [one, two, three]>,
# #<Lutaml::Model::ChoiceUpperBoundError: Attribute count exceeds the upper bound>
# ]
e = klin.validate!
# => Lutaml::Model::ValidationError: [
# degree_settings must have at least 1 element,
# description must be one of [one, two, three],
# Attribute count exceeds the upper bound
# ]
e.errors
# => [
# #<Lutaml::Model::CollectionSizeError: degree_settings must have at least 1 element>,
# #<Lutaml::Model::ValueError: description must be one of [one, two, three]>,
# #<Lutaml::Model::ChoiceUpperBoundError: Attribute count exceeds the upper bound>
# #<Lutaml::Model::ChoiceLowerBoundError: Attribute count is less than lower bound>
# ]
klin = Klin.new(degree_settings: [100, 200, 300], description: "one", prefix: "Ben")
klin.validate
# => [
# #<Lutaml::Model::RequiredAttributeMissingError: Missing required attribute: name>
# ]Custom validation
To add custom validation, override the validate method in the model class. Additional errors should be added to the errors array.
The following class validates the degree_settings attribute when the type is glass to ensure that the value is less than 1300.
class Klin < Lutaml::Model::Serializable
attribute :name, :string
attribute :type, :string, values: %w[glass ceramic]
attribute :degree_settings, :integer, collection: (1..)
def validate
errors = super
if type == "glass" && degree_settings.any? { |d| d > 1300 }
errors << Lutaml::Model::Error.new("Degree settings for glass must be less than 1300")
end
end
end
klin = Klin.new(name: "Klin", type: "glass", degree_settings: [100, 200, 1400])
klin.validate
# => [#<Lutaml::Model::Error: Degree settings for glass must be less than 1300>]