From 033b5ad3a820076b9da2f579f47cc8c669f6b5bc Mon Sep 17 00:00:00 2001 From: Justin Smestad Date: Wed, 8 Apr 2020 11:06:55 -0600 Subject: [PATCH 1/2] Support composite Ecto.Type definitions --- README.md | 11 ++++++----- lib/commanded/command.ex | 5 +++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7299e3d..fc59211 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,11 @@ defmodule CreateAccount do use Commanded.Command, username: :string, email: :string, - age: :integer + age: {:integer, default: 0}, + aliases: {{:array, :string}} # Composite Type requires extra brace to avoid being interprated as opts end -iex> CreateAccount.new() +iex> CreateAccount.new() #Ecto.Changeset, valid?: true> ``` @@ -54,7 +55,7 @@ defmodule CreateAccount do end end -iex> CreateAccount.new() +iex> CreateAccount.new() #Ecto.Changeset< action: nil, changes: %{}, @@ -67,7 +68,7 @@ iex> CreateAccount.new() valid?: false > -iex> changeset = CreateAccount.new(username: "chris", email: "chris@example.com", age: 5) +iex> changeset = CreateAccount.new(username: "chris", email: "chris@example.com", age: 5) #Ecto.Changeset< action: nil, changes: %{age: 5, email: "chris@example.com", username: "chris"}, @@ -149,7 +150,7 @@ iex> event = AccountCreated.new(cmd) You may have noticed that we provide a default version of `1`. -You can change the version of an event at anytime. +You can change the version of an event at anytime. After doing so, you should define an upcast instance that knows how to transform older events into the latest version. diff --git a/lib/commanded/command.ex b/lib/commanded/command.ex index 7cc197d..8aa7ce2 100644 --- a/lib/commanded/command.ex +++ b/lib/commanded/command.ex @@ -35,6 +35,8 @@ defmodule Commanded.Command do @primary_key false embedded_schema do Enum.map(unquote(schema), fn + {name, {{_, _} = composite_type, opts}} -> field(name, field_type(composite_type), opts) + {name, {{_, _} = composite_type}} -> field(name, field_type(composite_type)) {name, {type, opts}} -> field(name, field_type(type), opts) {name, type} -> field(name, field_type(type)) end) @@ -60,5 +62,8 @@ defmodule Commanded.Command do end def field_type(:binary_id), do: Ecto.UUID + def field_type(:array) do + raise "`:array` is not a valid Ecto.Type\nIf you are using a composite data type, wrap the type definition like this `{{:array, :string}}`" + end def field_type(type), do: type end From e35bae47d3fa26234783f3787184ac00d336a771 Mon Sep 17 00:00:00 2001 From: Justin Smestad Date: Wed, 8 Apr 2020 11:23:59 -0600 Subject: [PATCH 2/2] Update doctest for compound data types --- lib/commanded/command.ex | 9 +++++---- test/support/messages.ex | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/commanded/command.ex b/lib/commanded/command.ex index 8aa7ce2..7652ae3 100644 --- a/lib/commanded/command.ex +++ b/lib/commanded/command.ex @@ -6,18 +6,19 @@ defmodule Commanded.Command do use Commanded.Command, username: :string, email: :string, - age: :integer + age: :integer, + aliases: {{:array, :string}} def handle_validate(changeset) do changeset - |> validate_required([:username, :email, :age]) + |> validate_required([:username, :email, :age, :aliases]) |> validate_format(:email, ~r/@/) |> validate_number(:age, greater_than: 12) end end - iex> CreateAccount.new(username: "chris", email: "chris@example.com", age: 5) - #Ecto.Changeset, valid?: false> + iex> CreateAccount.new(username: "chris", email: "chris@example.com", age: 5, aliases: ["christopher", "kris"]) + #Ecto.Changeset, valid?: false> """ @doc """ diff --git a/test/support/messages.ex b/test/support/messages.ex index f403792..236c792 100644 --- a/test/support/messages.ex +++ b/test/support/messages.ex @@ -9,7 +9,8 @@ defmodule CreateAccount do use Commanded.Command, username: :string, email: :string, - age: :integer + age: :integer, + aliases: {{:array, :string}} def handle_validate(changeset) do changeset