Elixir and Behaviours by Ecto example
An Elixir behaviour is just a list of functions. A module that declares that it implements a particular behaviour must implement all of these functions.
I would say that behaviours are kind of interfaces from the OOP world.

Ecto uses behaviours for adding ability to create custom types. Let’s open ecto/lib/ecto/type.ex. @callback
directive is used to define befaviours. It expects a function name and function specification.
defmodule Ecto.Type do
@callback type :: t
@callback cast(term) :: {:ok, term} | :error
@callback load(term) :: {:ok, term} | :error
@callback dump(term) :: {:ok, term} | :error
...
end
So if you want to use custom types then you should implement all of these 4 functions: type
, cast
, load
and dump
. Otherwise elixir will throw a compilation warning.
arc_ecto uses ecto’s custom type generation:
defmodule Arc.Ecto.Definition do
defmacro __using__(_options) do
definition = __CALLER__.module
quote do
defmodule Module.concat(unquote(definition), “Type”) do
@behaviour Ecto.Type
def type, do: Arc.Ecto.Type.type
def cast(value) do
Arc.Ecto.Type.cast(unquote(definition), value)
end
def load(value), do: Arc.Ecto.Type.load(unquote(definition), value)
def dump(value), do: Arc.Ecto.Type.dump(unquote(definition), value)
end
end
...
end
@behaviour
declares that Arc.Ecto.Definition
implements Ecto.Type
and then defines necessary functions.
Then you can use Arc’s custom type in the your app:
defmodule Spark.ImageUploader do
use Arc.Definition
use Arc.Ecto.Definition
end
defmodule Spark.Gallery.Image do
use Ecto.Schema
use Arc.Ecto.Schema
schema "images" do
field :image, Spark.ImageUploader.Type
...
end
end
If you don’t clearly understand what is use
and why it is used here, please read my previous post about macros.
That’s all for today.
Thank you for reading this post!