An Ecto.Type storing a Localize.PersonName.t/0 as jsonb.
A person name is stored as a single JSON object rather than as a
column per part. CLDR models a name as eleven optional parts — a
surname prefix, other given names, a generation, credentials — and
any given name uses few of them, so a wide table of mostly empty
columns is the wrong shape. Parts that are nil are omitted from the
stored object entirely.
Storing the parts rather than a formatted string is what keeps the name formattable: the same record renders as "Dr. Herbert Fritz von Müller" or "Müller, Herbert" or "H. F. von Müller" depending on the locale, format and order asked for at display time.
Schema
jsonb is a built-in type, so nothing but the column is needed:
# in a migration
add :name, :map
# in a schema
field :name, Localize.PersonName.Ecto.Map.TypeStored form
The name parts are stored as strings under their field names. Two fields are not strings and are converted:
:preferred_orderis stored as its string form ("given_first","surname_first"or"sorting") and loaded back to the atom.:localeis stored as its canonical language tag ("de-DE") and loaded back to a resolvedLocalize.LanguageTag.t/0throughLocalize.validate_locale/1, so the name carries the locale that governs its formatting.
Casting
cast/1 accepts a person name struct, or a map keyed by either
strings or atoms — which is what an HTML form supplies. Unknown keys
are ignored, so a form carrying extra parameters does not fail.