Defines "Value Object" modules.
Summary
Functions
Converts the module into an Ecto.Schema and add factory functions to create structs.
Returns an Ecto.Changeset.t/0 for a given value object struct.
Creates a value object struct for the given module and attributes.
Creates a value object struct for the given module and attributes, raising on validation errors.
Functions
@spec __using__(opts :: []) :: any()
Converts the module into an Ecto.Schema and add factory functions to create structs.
Using
Derives
Usage
defmodule MyValueObject do
use Trogon.Commanded.ValueObject
embedded_schema do
field :title, :string
# ...
end
endOverridable
validate/2to add custom validation to the existingchangeset/2without overriding the wholechangeset/2function.defmodule MyValueObject do use Trogon.Commanded.ValueObject embedded_schema do field :amount, :integer end def validate(changeset, attrs) do changeset |> Changeset.validate_number(:amount, greater_than: 0) end endchangeset/2returns anEcto.Changeset.t/0for a given value object struct.Overriding Changeset
Be careful when overriding
changeset/2because the default implementation takes care ofcast,validate_requiredthe@enforced_keysand nested embeds. You may want to callTrogon.Commanded.ValueObject.changeset/2to have such features.If you only need to extend the changeset, you can override the
validate/2function instead.
Returns an Ecto.Changeset.t/0 for a given value object struct.
It reads the @enforced_keys from the struct and validates the required
fields. Also, it casts the embeds. It is useful when you override the
changeset/2 function in your value object.
Examples
defmodule MyValueObject do
use Trogon.Commanded.ValueObject
@enforce_keys [:title, :amount]
embedded_schema do
field :title, :string
field :amount, :integer
end
def changeset(message, attrs) do
message
|> ValueObject.changeset(attrs)
|> Changeset.validate_number(:amount, greater_than: 0)
end
end
@spec new(struct_module :: atom(), attrs :: map()) :: {:ok, struct()} | {:error, Ecto.Changeset.t()}
Creates a value object struct for the given module and attributes.
This function applies the changeset validation logic defined in the value object
module and returns either {:ok, struct} on success or {:error, changeset}
when validation fails.
Parameters
struct_module- The value object module that usesTrogon.Commanded.ValueObjectattrs- A map of attributes to create the value object with
Examples
Creating a simple value object:
iex> Trogon.Commanded.ValueObject.new(TestSupport.MessageOne, %{title: "Hello"})
{:ok, %TestSupport.MessageOne{title: "Hello"}}Creating a value object with validation:
iex> Trogon.Commanded.ValueObject.new(TestSupport.TransferableMoney, %{amount: 100, currency: :USD})
{:ok, %TestSupport.TransferableMoney{amount: 100, currency: :USD}}Validation failure example:
iex> {:error, changeset} = Trogon.Commanded.ValueObject.new(TestSupport.TransferableMoney, %{amount: -5, currency: :USD})
iex> changeset.valid?
falseMissing required field:
iex> {:error, changeset} = Trogon.Commanded.ValueObject.new(TestSupport.MyValueOject, %{amount: 25})
iex> changeset.valid?
false
Creates a value object struct for the given module and attributes, raising on validation errors.
This function is similar to new/2 but raises an Ecto.InvalidChangesetError
instead of returning an error tuple when validation fails.
Parameters
struct_module- The value object module that usesTrogon.Commanded.ValueObjectattrs- A map of attributes to create the value object with
Examples
Creating a simple value object:
iex> Trogon.Commanded.ValueObject.new!(TestSupport.MessageOne, %{title: "Hello"})
%TestSupport.MessageOne{title: "Hello"}Creating a value object with validation:
iex> Trogon.Commanded.ValueObject.new!(TestSupport.TransferableMoney, %{amount: 100, currency: :USD})
%TestSupport.TransferableMoney{amount: 100, currency: :USD}Validation failure raises an exception:
iex> try do
...> Trogon.Commanded.ValueObject.new!(TestSupport.TransferableMoney, %{amount: -5, currency: :USD})
...> rescue
...> Ecto.InvalidChangesetError -> :error_raised
...> end
:error_raisedMissing required field raises an exception:
iex> try do
...> Trogon.Commanded.ValueObject.new!(TestSupport.MyValueOject, %{amount: 25})
...> rescue
...> Ecto.InvalidChangesetError -> :error_raised
...> end
:error_raised