View Source EctoDiscriminator.Schema (ecto_discriminator v0.4.4)
Wrapper around Ecto.Schema
that enables inheritance of schema fields.
It has been built to mimic Ecto.Schema
as much as possible.
base-schema
Base schema
To make a base schema you have to do two things:
Change
use Ecto.Schema
touse EctoDiscriminator.Schema
:defmodule SomeTable do use EctoDiscriminator.Schema
Add
EctoDiscriminator.DiscriminatorType
field to schema (check module documentation for more examples):schema "some_table" do field :type, EctoDiscriminator.DiscriminatorType ... end
Base schemas should ideally contain only fields that are common across all diverged schemas (like timestamps). There is no problem with having other fields defined if someone needs it for some functionality though. Any field can be overriden by diverged schema.
Diverged changeset
Base schemas have predefined function, based on DiscriminatorChangeset.diverged_changeset/2
,
that allows creating changesets for diverged schemas directly from base (check here for more).
diverged-schema
Diverged schema
To make a diverged schema you have to do two things:
Change
use Ecto.Schema
touse EctoDiscriminator.Schema
:defmodule SomeTable.Foo do use EctoDiscriminator.Schema
Define schema with name of base schema as a source:
schema SomeTable do field ... ... end
Diverged schemas can contain any field supported by Ecto.Schema
.
Inheriting struct-related stuff
@derive
Any @derive
declarations put in base schema will be applied to the diverged schema. You can still overwrite those for particular schema if needed.
Going back to base struct
Base struct
Diverged schemas have predefined function to_base/1
that applies simple modifications in order to get base struct from diverged.
Base changeset
Diverged schemas have predefined function, based on DiscriminatorChangeset.base_changeset/2
,
that allows creating changesets for base schemas directly from diverged (check here for more).
Casting base fields
Diverged schemas have predefined function, based on DiscriminatorChangeset.cast_base/2
,
that allows running base changesets inside changeset of diverged schema
(check here for more).
querying
Querying
Diverged schemas have some logic injected that allows very simple querying:
MyApp.Repo.all(SomeTable.Foo)
This will generate SQL similar to this:
SELECT ... FROM some_table WHERE discriminator = "Elixir.SomeTable.Foo"
This functionality should be enough in most cases,
however if the injected where
condition causes some issues (eg. in some advanced SQL) you can exclude it on the beginning:
SomeTable.Foo
|> exclude(:where)
|> MyApp.Repo.all()
#=> SELECT ... FROM some_table
Link to this section Summary
Functions
Main building block for inheritance logic.
Link to this section Functions
Main building block for inheritance logic.
schema/2
wraps Ecto.Schema.schema/2
, adding some features required to support idea of this library.
For base schema, source
should be the name of a DB table:
schema "some_table" do
For diverged schema, source
must be the name of a base module:
schema SomeTable do
Additionally, inside schema/2
of the base schema you have to add field which will be acting as a discriminator:
field :type, EctoDiscriminator.DiscriminatorType