EctoMorph.cast_to_struct

You're seeing just the function cast_to_struct, go back to EctoMorph module for more information.
Link to this function

cast_to_struct(data, schema)

View Source

Specs

cast_to_struct(map() | ecto_struct(), schema_module()) ::
  okay_struct() | error_changeset()

Takes some data and tries to convert it to a struct in the shape of the given schema. Casts values to the types defined by the schema dynamically using ecto changesets.

Consider this:

iex> Jason.encode!(%{a: :b, c: Decimal.new("10")}) |> Jason.decode!
%{"a" => "b", "c" => "10"}

When we decode some JSON (e.g. from a jsonb column in the db or from a network request), the JSON gets decoded by our Jason lib, but not all of the information is preserved; any atom keys become strings, and if the value is a type that is not part of the JSON spec, it is casted to a string.

This means we cannot pass that JSON data directly into a struct/2 function and expect a shiny Ecto struct back (struct!/2 will just raise, and struct/2 will silently return an empty struct)

UNTIL NOW!

Here we take care of casting the values in the json to the type that the given schema defines, as well as turning the string keys into (existing) atoms. (We know they will be existing atoms because they will exist in the schema definitions.)

We filter out any keys that are not defined in the schema, and if the first argument is a struct, we call Map.from_struct/1 on it first. This can be useful for converting data between structs.

Check out the tests for more full examples.

Examples

iex> defmodule Test do
...>   use Ecto.Schema
...>
...>   embedded_schema do
...>     field(:pageviews, :integer)
...>   end
...> end
...> {:ok, test = %Test{}} = cast_to_struct(%{"pageviews" => "10"}, Test)
...> test.pageviews
10

iex> defmodule Test do
...>   use Ecto.Schema
...>
...>   embedded_schema do
...>     field(:pageviews, :integer)
...>   end
...> end
...> json = %{"pageviews" => "10", "ignored_field" => "ten"}
...> {:ok, test = %Test{}} = cast_to_struct(json, Test)
...> test.pageviews
10
Link to this function

cast_to_struct(data, schema, fields)

View Source

Specs

cast_to_struct(map() | ecto_struct(), schema_module(), list()) ::
  okay_struct() | error_changeset()

Takes some data and tries to convert it to a struct in the shape of the given schema. Casts values to the types defined by the schema dynamically using ecto changesets.

Accepts a whitelist of fields that you allow updates / inserts on. This list of fields can define fields for inner schemas also like so:

  EctoMorph.cast_to_struct(json, SchemaUnderTest, [
    :boolean,
    :name,
    :binary,
    :array_of_ints,
    steamed_hams: [:pickles, double_nested_schema: [:value]]
  ])

We filter out any keys that are not defined in the schema, and if the first argument is a struct, we call Map.from_struct/1 on it first. This can be useful for converting data between structs.