Getting Started
Introduction
Paradocs = Extended Parametric gem + Documentation Generation
Declaratively define data schemas in your Ruby objects, and use them to whitelist, validate or transform inputs to your programs.
Useful for building self-documeting APIs, search or form objects. Or possibly as an alternative to Rails' strong parameters (it has no dependencies on Rails and can be used stand-alone).
Installation
$ gem install paradocs
Or with Bundler in your Gemfile.
gem 'paradocs'
Try it out
Define a schema
schema = Paradocs::Schema.new do
field(:title).type(:string).present
field(:status).options(["draft", "published"]).default("draft")
field(:tags).type(:array)
end
Populate and use. Missing keys return defaults, if provided.
form = schema.resolve(title: "A new blog post", tags: ["tech"])
form.output # => {title: "A new blog post", tags: ["tech"], status: "draft"}
form.errors # => {}
Undeclared keys are ignored.
form = schema.resolve(foobar: "BARFOO", title: "A new blog post", tags: ["tech"])
form.output # => {title: "A new blog post", tags: ["tech"], status: "draft"}
Validations are run and errors returned
form = schema.resolve({})
form.errors # => {"$.title" => ["is required"]}
If options are defined, it validates that value is in options
form = schema.resolve({title: "A new blog post", status: "foobar"})
form.errors # => {"$.status" => ["expected one of draft, published but got foobar"]}
Nested schemas
A schema can have nested schemas, for example for defining complex forms.
person_schema = Paradocs::Schema.new do
field(:name).type(:string).required
field(:age).type(:integer)
field(:friends).type(:array).schema do
field(:name).type(:string).required
field(:email).policy(:email)
end
end
It works as expected
results = person_schema.resolve(
name: "Joe",
age: "38",
friends: [
{name: "Jane", email: "jane@email.com"}
]
)
results.output # => {name: "Joe", age: 38, friends: [{name: "Jane", email: "jane@email.com"}]}
Validation errors use JSON path expressions to describe errors in nested structures
results = person_schema.resolve(
name: "Joe",
age: "38",
friends: [
{email: "jane@email.com"}
]
)
results.errors # => {"$.friends[0].name" => "is required"}