I’m writing an app, ExtDep
, that’s intended to be used as a dependency in other apps. It defines some schemas, but I’m struggling to find a design that lets callers (extend|compose|customise) those schemas—like defining a custom primary_key
.
The out of the box experience is as you’d expect from a typical callback-module app. There’s some runtime configuration, a boundary context in ExtDep
that’s invoked from YourApp
, and some work that happens in the configured repo.
deps/ext_dep/lib/schemas.ex
defmodule ExtDep.SomeSchema do
use Ecto.Schema
schema "some_schemas" do
field :some_column, :string
end
end
defmodule ExtDep.SomeSchemaAssoc do
use Ecto.Schema
schema "some_schemas_assocs" do
field :assoc_column, :string
belongs_to :some_schema, ExtDep.SomeSchema
end
end
deps/ext_dep/lib/ext_dep.ex
defmodule ExtDep do
...
def bar(args) do
schema = create_schema(args)
config().repo.insert(schema)
end
end
config.exs
config :your_app, ExtDep,
repo: YourApp.Repo
lib/your_app/some_module.ex
defmodule YourApp.SomeModule do
def foo(args) do
ExtDep.bar(args)
end
end
Ecto’s docs provide an example for defining a custom schema to override the default primary_key
and foreign_key_type
attributes in schemas you control:
lib/your_app/schema.ex
defmodule YourApp.Schema do
defmacro __using__(_) do
quote do
use Ecto.Schema
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
end
end
end
I thought about rewriting ExtDep
's schemas to leverage a __using__
macro, something like:
defmodule ExtDep.SomeSchema do
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
use Keyword.get(opts, :schema, Ecto.Schema)
schema ..., do: ...
end
end
end
defmodule YourApp.SomeSchema do
use ExtDep.SomeSchema, schema: YourApp.Schema
end
But that’s not going to work because use
expects a module that’s available at compile time.
The other consideration I have is that if the calling application provides its own module, the belongs_to :some_schema, ExtDep.SomeSchema
field is not going to work.
Is the idea of customising a dependencies schema sane?