Embedded schema for form validation and casting
As useful as Ecto schemas are for databases, they are just as compelling for handling Form parameters. The key is using embedded_schema.
Define an embedded_schema that represents the request parameters with the types:
defmodule P do
use Ecto.Schema
embedded_schema do
field :an_int, :integer
field :a_date, :date
end
end
Then use cast to get the parameters safely and with typing into a changeset:
iex(3)> p = cast( %P{}, %{ "an_int" => "4", "a_date" => "2019-04-04" }, [ :an_int, :a_date ] )
#Ecto.Changeset<
action: nil,
changes: %{a_date: ~D[2019-04-04], an_int: 4},
errors: [],
data: #P<>,
valid?: true
>
If the changeset is valid, then you can use apply_changes to get the struct you wanted:
iex(5)> apply_changes(p)
%P{a_date: ~D[2019-04-04], an_int: 4, id: nil}
You can also use all the typical validators the Changeset offers.
If some of the data is bad/mistyped, the changeset will mark it as valid? false:
iex(6)> cast( %P{}, %{ "an_int" => "fred", "a_date" => "2019-04-04" }, [ :an_int, :a_date ] )
#Ecto.Changeset<
action: nil,
changes: %{a_date: ~D[2019-04-04]},
errors: [an_int: {"is invalid", [type: :integer, validation: :cast]}],
data: #P<>,
valid?: false
>