Klon simplifies cloning of database records via Ecto with a simple API and
flexible, user-defined protocol implementations.
If available in Hex, the package can be installed
by adding klon to your list of dependencies in mix.exs:
def deps do
[
{:klon, "~> 0.1.0"}
]
endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/klon.
Define an implementation for an Ecto.Schema:
defmodule Parent do
use Ecto.Schema
defimpl Klon.Clonable do
def assocs(_parent), do: ~w(children)a
def change(parent, params), do: Ecto.Changeset.change(parent, params)
# Delegate to avoid boilerplate.
defdelegate multi(parent, name, changeset), to: Klon.Clonable.Default
end
schema "parents" do
field :example, :integer
has_many :children, Child
end
endThe protocol may instead be derived with zero or more options:
defmodule Child do
use Ecto.Schema
@derive Klon.Clonable
schema "children" do
field :example, :integer
belongs_to :parent, Parent
end
endSee Klon.Clonable for documentation on implementations.
Clone the record:
# Using a multi
{:ok, changes} = source |> Klon.clone() |> Repo.transaction()
# Using a callback
Repo.transaction(fn ->
{:ok, changes} = source |> Klon.clone() |> Repo.transaction()
changes
end)The clone may be accessed via the source in the changes:
clone = Map.fetch!(changes, Klon.name(source))
^clone = Klon.value(source, changes)
{^source, ^clone} = Klon.pair(source, changes)