ImplicitSchema
Lazily and implicitly validate Hash objects (e.g. from JSON::parse)
Author: Shaun Mangelsdorf
Copyright 2015, Australian Access Federation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Installation
Add this line to your application's Gemfile:
gem 'implicit-schema'
Use Bundler to install the dependency:
bundle install
Usage
Though tools are available for validating JSON documents, it's often more convenient to assume the payload is valid and allow an exception to occur if that's not the case (after all, the result of failed validation is typically an exception anyway). The only problem with this approach comes when your logic becomes more complex:
class SomeDataProcessor
def process(data)
data[:people].each { |p| descend(p) }
end
def descend(person)
person[:employer][:contact][:phone] # NoMethodError: undefined method `[]' for nil:NilClass
end
end
When the error occurs, there's no easy way to know which key was missing and
resulted in the nil
value.
ImplicitSchema is typically used to wrap the output of JSON parsing. That is:
json = '{"a": 1, "b": 2, "c": 3}'
data = JSON.parse(json, symbolize_names: true)
obj = ImplicitSchema.new(data)
obj[:a] # 1
obj[:b] # 2
obj[:d] # ImplicitSchema::ValidationError: Missing key: `:d` - available keys: (:a, :b, :c)
Nested Hash objects are automatically wrapped:
obj = ImplicitSchema.new(a: { b: { c: 1 } })
obj[:a] # { b: { c: 1 } } (wrapped)
obj[:a][:b] # { c: 1 } (wrapped)
obj[:a][:b][:c] # 1
obj[:a][:b][:d] # ImplicitSchema::ValidationError: Missing key: `:d` - available keys: (:c)
Nested Array objects are also processed in the same way:
obj = ImplicitSchema.new(a: [
{ x: 1, y: 2, z: 3 },
{ x: 4, y: 5, z: 6 }
])
obj[:a] # an Array
obj[:a][0] # { x: 1, y: 2, z: 3 } (wrapped)
obj[:a][0][:x] # 1
obj[:a][0][:w] # ImplicitSchema::ValidationError: Missing key: `:w` - available keys: (:x, :y, :z)
Contributing
Refer to GitHub Flow for help contributing to this project.