Skip to content

Instantly share code, notes, and snippets.

@khpatel4991
Created January 4, 2017 23:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khpatel4991/e9d6fd9899ee927b54a9ca2dffb937eb to your computer and use it in GitHub Desktop.
Save khpatel4991/e9d6fd9899ee927b54a9ca2dffb937eb to your computer and use it in GitHub Desktop.
Nested Dry Validations
class AppSchema < Dry::Validation::Schema::Form
configure do |config|
config.type_specs = true
def self.messages
super.merge(
en: { errors: {
discount_pricing: 'are not valid.',
base_package_price: 'You need to have a package_price with quantity 1.',
package_names: 'should be unique.'
} }
)
end
end
def unique_package_names?(packages)
name_set = Set.new
valid = true
packages.each do |package|
package_struct = OpenStruct.new(package)
name = package_struct.name
if name_set.include?(name)
valid = false
break
end
name_set.add(name)
end
valid
end
def base_package_price_exists?(prices)
valid = false
prices.each do |package_price|
price_obj = OpenStruct.new(package_price)
if price_obj.quantity == 1
valid = true
break
end
end
valid
end
def valid_discount_prices?(prices)
max_quantity = 0
max_price = Float::MAX
quantity_set = Set.new
valid = true
prices.each do |price_obj|
price_obj = OpenStruct.new(price_obj)
if quantity_set.include? price_obj.quantity
valid = false
break
end
quantity_set.add(price_obj.quantity)
if price_obj.quantity > max_quantity
if price_obj.unit_price < max_price
max_quantity = price_obj.quantity
max_price = price_obj.unit_price
else
valid = false
break
end
else
if price_obj.unit_price <= max_price
valid = false
break
end
end
end
valid
end
end
pp = Dry::Validation.Schema do
required(:unit_price).filled(:float?)
required(:quantity).filled(:int?)
end
p = Dry::Validation.Schema do
optional(:id).maybe(:int?)
required(:name).filled(:str?)
required(:package_prices).each { schema pp }
validate(discount_pricing: :package_prices) do |package_prices|
base_package_price_exists?(package_prices) && valid_discount_prices?(package_prices)
end
end
s = Dry::Validation.Schema(AppSchema) do
required(:title).filled(:str?)
required(:packages).each { schema p }
validate(package_names: :packages) { :unique_package_names? }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment