TypedEctoSchema
TypedEctoSchema provides a DSL on top of Ecto.Schema to define schemas with typespecs
without all the boilerplate code.
To add type information to an Ecto.Schema, you normally have to keep the fields, the
@enforce_keys and a hand-written @type t() in sync, repeating every field name three
times:
defmodule Person do
use Ecto.Schema
@enforce_keys [:name]
schema "people" do
field(:name, :string)
field(:age, :integer)
field(:happy, :boolean, default: true)
field(:phone, :string)
belongs_to(:company, Company)
timestamps(type: :naive_datetime_usec)
end
@type t() :: %__MODULE__{
__meta__: Ecto.Schema.Metadata.t(),
id: integer() | nil,
name: String.t(),
age: non_neg_integer() | nil,
happy: boolean(),
phone: String.t() | nil,
company_id: integer() | nil,
company: Company.t() | Ecto.Association.NotLoaded.t() | nil,
inserted_at: NaiveDateTime.t() | nil,
updated_at: NaiveDateTime.t() | nil
}
end
With typed_ecto_schema the same schema — typespec, enforced keys and all — is just:
defmodule Person do
use TypedEctoSchema
typed_schema "people" do
field(:name, :string, enforce: true, null: false)
field(:age, :integer) :: non_neg_integer() | nil
field(:happy, :boolean, default: true, null: false)
field(:phone, :string)
belongs_to(:company, Company)
timestamps(type: :naive_datetime_usec)
end
end
Installation
Add it to your deps:
{:typed_ecto_schema, "~> 0.5.0", runtime: false}
Then replace use Ecto.Schema with use TypedEctoSchema, and the calls to schema with
typed_schema and embedded_schema with typed_embedded_schema.
Features
The full documentation lives on hexdocs. At a glance:
- Automatic typespec inference
for fields, associations, embeds and the fields Ecto generates behind the scenes
(primary key, foreign keys, timestamps,
__meta__). ::overrides to narrow or replace any inferred typespec inline.:nulland:enforceoptions on fields, associations, embeds,timestamps()and the@primary_keyattribute, controlling nullability and@enforce_keys.- Field documentation
via the
:docoption, rendered into your@moduledocthrough a marker and into a generated@typedoc. - Experimental:
named types for
Ecto.Enumfields and apolymorphic_embedintegration.
There is also a cheatsheet with every option at a glance, and a changelog.
Credits
This project started as a fork of the awesome typed_struct.
That being said, I'd like to give some special thanks to
- Jean-Philippe Cugnet for laying the ground for this work.
- Carlos Brito Lage for helping me with planning and ideas about the DSL.