Conceptually, you can’t determine if a field like friends has valid values in it without a larger context than the single Person.
When persisting things to the database, the database acts as that context.
If you aren’t persisting the data, then that context is the whole group of Person structs being decoded.
That’s not exactly a “second run”, but it’s similar:
- decode each
Person - pass the whole list to a function that checks
friendsfor internal consistency: refers to people that exist, is properly reflexive (if desired)
Re: EctoAtom - String.to_atom still makes people pretty worried. What about specific types for the various things:
defmodule Job do
@type id_t() :: :job_mechanic | :job_doc | :job_programmer
use Ecto.Type
def type, do: :atom
def cast("job_mechanic"), do: {:ok, :job_mechanic}
def cast("job_doc"), do: {:ok, :job_doc}
def cast("job_programmer"), do: {:ok, :job_programmer}
def cast(_), do: :error
def load("job_mechanic"), do: {:ok, :job_mechanic}
def load("job_doc"), do: {:ok, :job_doc}
def load("job_programmer"), do: {:ok, :job_programmer}
def load(_), do: :error
def dump(:job_mechanic), do: {:ok, "job_mechanic"}
def dump(:job_doc), do: {:ok, "job_doc"}
def dump(:job_programmer), do: {:ok, "job_programmer"}
def dump(_}, do: :error
end
Then the fields are more specific about what they contain:
field(:job, Job) :: Job.id_t()
field(:hobbies, {:array, Hobby}) :: [Hobby.id_t()]






















