View Source Ecto.ParameterizedType behaviour (Ecto v3.12.2)
Parameterized types are Ecto types that can be customized per field.
Parameterized types allow a set of options to be specified in the schema which are initialized on compilation and passed to the callback functions as the last argument.
For example, field :foo, :string
behaves the same for every field.
On the other hand, field :foo, Ecto.Enum, values: [:foo, :bar, :baz]
will likely have a different set of values per field.
Note that options are specified as a keyword, but it is idiomatic to
convert them to maps inside init/1
for easier pattern matching in
other callbacks.
Parameterized types are a superset of regular types. In other words,
with parameterized types you can do everything a regular type does,
and more. For example, parameterized types can handle nil
values
in both load
and dump
callbacks, they can customize cast
behavior
per query and per changeset, and also control how values are embedded.
However, parameterized types are also more complex. Therefore, if everything you need to achieve can be done with basic types, they should be preferred to parameterized ones.
Examples
To create a parameterized type, create a module as shown below:
defmodule MyApp.MyType do
use Ecto.ParameterizedType
def type(_params), do: :string
def init(opts) do
validate_opts(opts)
Enum.into(opts, %{})
end
def cast(data, params) do
...
{:ok, cast_data}
end
def load(data, _loader, params) do
...
{:ok, loaded_data}
end
def dump(data, dumper, params) do
...
{:ok, dumped_data}
end
def equal?(a, b, _params) do
a == b
end
end
To use this type in a schema field, specify the type and parameters like this:
schema "foo" do
field :bar, MyApp.MyType, opt1: :baz, opt2: :boo
end
To use this type in places where you need it to be initialized (for example,
schemaless changesets), you can use init/2
.
use Ecto.ParameterizedType
When you
use Ecto.ParameterizedType
, it will set@behaviour Ecto.ParameterizedType
and define default, overridable implementations forembed_as/2
andequal?/3
.
Summary
Types
The parameters for the ParameterizedType
Callbacks
Generates a loaded version of the data.
Casts the given input to the ParameterizedType with the given parameters.
Dumps the given term into an Ecto native type.
Dictates how the type should be treated inside embeds.
Checks if two terms are semantically equal.
Formats output when a ParameterizedType is printed in exceptions and other logs.
Callback to convert the options specified in the field macro into parameters to be used in other callbacks.
Loads the given term into a ParameterizedType.
Returns the underlying schema type for the ParameterizedType.
Functions
Inits a parameterized type given by type
with opts
.
Types
Callbacks
Generates a loaded version of the data.
This callback is invoked when a parameterized type is given
to field
with the :autogenerate
flag.
Casts the given input to the ParameterizedType with the given parameters.
If the parameterized type is also a composite type,
the inner type can be cast by calling Ecto.Type.cast/2
directly.
For more information on casting, see Ecto.Type.cast/1
.
Dumps the given term into an Ecto native type.
It receives a dumper
function in case the parameterized
type is also a composite type. In order to dump the inner
type, the dumper
must be called with the inner type and
the inner value as argument.
For more information on dumping, see Ecto.Type.dump/1
.
Note that this callback will be called when dumping a nil
value, unlike Ecto.Type.dump/1
.
Dictates how the type should be treated inside embeds.
For more information on embedding, see Ecto.Type.embed_as/1
Checks if two terms are semantically equal.
Formats output when a ParameterizedType is printed in exceptions and other logs.
Note this callback is not used when constructing Ecto.Changeset
validation
errors. See the :message
option of most Ecto.Changeset
validation
functions for how to customize error messaging on a per Ecto.Changeset
basis.
Callback to convert the options specified in the field macro into parameters to be used in other callbacks.
This function is called at compile time, and should raise if invalid values are
specified. It is idiomatic that the parameters returned from this are a map.
field
and schema
will be injected into the options automatically.
For example, this schema specification
schema "my_table" do
field :my_field, MyParameterizedType, opt1: :foo, opt2: nil
end
will result in the call:
MyParameterizedType.init([schema: "my_table", field: :my_field, opt1: :foo, opt2: nil])
Loads the given term into a ParameterizedType.
It receives a loader
function in case the parameterized
type is also a composite type. In order to load the inner
type, the loader
must be called with the inner type and
the inner value as argument.
For more information on loading, see Ecto.Type.load/1
.
Note that this callback will be called when loading a nil
value, unlike Ecto.Type.load/1
.
@callback type(params()) :: Ecto.Type.t()
Returns the underlying schema type for the ParameterizedType.
For more information on schema types, see Ecto.Type.type/0
Functions
Inits a parameterized type given by type
with opts
.
Useful when manually initializing a type for schemaless changesets.