defmodule Formy do defmacro __using__(_) do quote do use Ecto.Schema import Ecto.Changeset import Formy def build(params \\ %{}) do fields = __MODULE__.__schema__(:fields) struct = __MODULE__.__struct__() changeset = struct |> cast(params, fields) |> validate_required(required_fields(params)) if changeset.valid? do {:ok, apply_changes(changeset)} else {:error, prepare_errors(changeset)} end end def required_fields(_params) do __MODULE__.__schema__(:fields) end def prepare_errors(changeset) do traverse_errors(changeset, fn({msg, _opts}) -> msg end) end defoverridable required_fields: 1, prepare_errors: 1 end end defmacro object([do: block]) do quote do @primary_key false embedded_schema([do: unquote(block)]) end end defmacro property(name, type \\ :string, opts \\ []) do quote do field(unquote(name), unquote(type), unquote(opts)) end end end