I am not sure if supporting use/* is the right way forward here. The `Kernel.use/2` macro is reserved for invoking a module's `__using__/1` macro. To be honest, I don't like the fact that you're setting the module attributes and defining the `embedded_schema` in the same macro. You can easily just define the `@primary_key` in the `__using__/1` macro and explicitly define the `embedded_schema` in `CreateRecurringTransfer` itself, but that's my preference.
Either way, if you have defined a `__using__/3` macro, you can always invoke it explicitly. Although I would rename it to avoid any confusion for developers reading the code in the future and potentially thinking it has something to do with `Kernel.use/2`.
defmodule Command do
defmacro aggregate_schema(opts \\ [], do: block) do
unless Keyword.has_key?(opts, :aggregate_identifier) do
raise ArgumentError, "Missing :aggregate_identifier key"
end
aggregate_identifier = Keyword.fetch!(opts, :aggregate_identifier)
quote do
use Ecto.Schema
@primary_key { @aggregate_identifier_key, :binary_id, autogenerate: true }
@derive Jason.Encoder
embedded_schema unquote(block)
end
end
end
defmodule CreateRecurringTransfer do
require Command
Command.aggregate_schema [aggregate_identifier: :id] do
field(:dtstart, :naive_datetime)
field(:dtend, :naive_datetime)
embeds_one(:amount, PositiveAmount)
embeds_one(:rrule, Rrule)
embeds_one(:owned_by, CustomerIdentity)
embeds_one(:from_account, TransferAccount)
embeds_one(:to_account, TransferAccount)
end
end