# `Localize.PersonName.Ecto.Map.Type`
[🔗](https://github.com/elixir-localize/localize_person_names/blob/v1.1.0/lib/localize/person_name/ecto/map_type.ex#L2)

An `Ecto.Type` storing a `t: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.Type

### Stored form

The name parts are stored as strings under their field names. Two
fields are not strings and are converted:

* `:preferred_order` is stored as its string form (`"given_first"`,
  `"surname_first"` or `"sorting"`) and loaded back to the atom.

* `:locale` is stored as its canonical language tag (`"de-DE"`) and
  loaded back to a resolved `t:Localize.LanguageTag.t/0` through
  `Localize.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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
