NLdoc.Spec.Schema (NLdoc.Spec v3.1.1)
View SourceThis module sets some defaults over the Ecto schema for the NLdoc spec.
- Use this in all schemas for the NLdoc spec, instead of
use Ecto.Schema
oruse TypedEctoSchema
:use NLdoc.Spec.Schema, type: "https://spec.nldoc.nl/Resource/Foo"
- Implement the
changeset/2
function in the schema module. - Make sure to add
@cast_opts
to all calls tocast/4
orcast_embed/3
orcast_polymorphic_embed/3
, as it ensures strings that only contain whitespace are accepted as valid.
Note: the type
option is required and must be a string. It is the resource type of the schema.
It will be available as @resource_type
in the schema module and through the resource_type/0
function on the schema module.
Summary
Functions
Collects all errors from a changeset and its nested changesets into a flat map, mapping the full JSON path of each property to its error.
This macro defines the new/1
and new!/1
functions for the schema module that create a new document from a template,
which essentially functions like an input-validating constructor for the struct defined by the schema module.
This macro maps a list of modules to a list of tuples with the module's resource type and the module itself. It's a macro because Ecto's schema definitions require this mapping to be done at compile time.
Returns true if the given module is an existing module.
Returns true for a module that is a schema module, i.e. it has a new/1
and a changeset/2
function.
This function validates whether a string is a valid URL, returning nil if it's valid
and an Ecto.Changeset.error()
if it's not.
Types
@type errors() :: %{required(property :: atom()) => Ecto.Changeset.error()}
@type validate_url_opt() :: {:allow_relative, boolean()}
Functions
@spec collect_errors(Ecto.Changeset.t()) :: errors()
Collects all errors from a changeset and its nested changesets into a flat map, mapping the full JSON path of each property to its error.
Example
iex> changeset = %Ecto.Changeset{
...> changes: [
...> descriptors: [
...> %Ecto.Changeset{errors: [url: {"is invalid", [validation: :invalid_url]}]}
...> ]
...> ],
...> errors: [
...> name: {"is invalid", [type: :string]}
...> ]
...> }
iex> NLdoc.Spec.Schema.collect_errors(changeset)
%{
name: {"is invalid", [type: :string]},
"descriptors[0].url": {"is invalid", [validation: :invalid_url]}
}
@spec collect_errors(Ecto.Changeset.t(), parent :: atom() | String.t()) :: errors()
@spec collect_errors([Ecto.Changeset.t() | any()], parent :: atom() | String.t()) :: errors()
This macro defines the new/1
and new!/1
functions for the schema module that create a new document from a template,
which essentially functions like an input-validating constructor for the struct defined by the schema module.
This macro maps a list of modules to a list of tuples with the module's resource type and the module itself. It's a macro because Ecto's schema definitions require this mapping to be done at compile time.
Example:
> NLdoc.Schema.map([Heading, Image])
[
"https://spec.nldoc.nl/Resource/Heading": Heading,
"https://spec.nldoc.nl/Resource/Image": Image
]
Returns true if the given module is an existing module.
Returns true for a module that is a schema module, i.e. it has a new/1
and a changeset/2
function.
@spec validate_url(String.t(), [validate_url_opt()]) :: Ecto.Changeset.error() | nil
This function validates whether a string is a valid URL, returning nil if it's valid
and an Ecto.Changeset.error()
if it's not.
Examples
iex> NLdoc.Spec.Schema.validate_url("http://localhost:4000")
nil
iex> NLdoc.Spec.Schema.validate_url("https://nldoc.nl/path/to/resource?query=string#fragment")
nil
iex> NLdoc.Spec.Schema.validate_url("https://no-tld")
nil
iex> NLdoc.Spec.Schema.validate_url("test")
{"is not a valid URL", error: [invalid_scheme: nil]}
iex> NLdoc.Spec.Schema.validate_url("/path/to/resource")
{"is not a valid URL", error: [invalid_scheme: nil, invalid_host: "/path/to/resource"]}