The default translation store, keeping translations on the subject itself.
Translations live in a single container field on the struct — a jsonb
column for an Ecto schema — shaped as a map of locale to a map of field to
value:
%{
"es" => %{"title" => "Título", "body" => "Cuerpo"},
"fr" => %{"title" => "Titre"}
}One row holds a record and all of its translations, so reading them costs no
join and no second query. This is the storage model Localize.Translate has
always used; the behaviour simply makes it swappable.
Both string and atom keys are accepted at every level, because a struct loaded from the database carries string keys while one built in Elixir may carry atoms.
This store is queryable: Localize.Translate.QueryBuilder pushes predicates
into SQL against the container column.