defmodule Flagsmith.Schemas.Traits.Trait do use TypedEctoSchema import Ecto.Changeset @moduledoc """ Ecto schema representing a Flagsmith trait definition and helpers to cast responses from the api. """ @primary_key {:id, :id, autogenerate: false} typed_embedded_schema do field(:trait_key, :string) field(:trait_value, __MODULE__.Value) end @spec changeset(map()) :: Ecto.Changeset.t() @spec changeset(__MODULE__.t(), map()) :: Ecto.Changeset.t() def changeset(struct \\ %__MODULE__{}, params) do struct |> cast(params, [:trait_value, :trait_key, :id]) |> validate_required([:trait_value, :trait_key]) end def extract_trait_value(key, traits) do case Enum.find(traits, fn %{trait_key: t_key} -> key == t_key end) do %__MODULE__{trait_value: %{value: value}} -> {:ok, value} _ -> {:error, :not_found} end end def from(traits) when is_list(traits), do: Enum.map(traits, &from/1) def from(%__MODULE__{} = trait), do: trait def from(%{} = params) do %__MODULE__{} |> cast(params, [:trait_value, :trait_key, :id]) |> validate_required([:trait_value]) |> apply_changes() end def into_update_map(traits) when is_list(traits) do traits |> Enum.reduce(%{}, fn %{trait_key: key, trait_value: value}, acc -> Map.put(acc, key, value) end) end end