Uni Ecto Plugin Now

  • Home
  • Cleaning service

Uni Ecto Plugin Now

step = Ecto.update(changeset)

Works identically to insert, but for an existing record.

defmodule Uni.Plugin.SoftDelete do
  @behaviour Uni.Plugin

def prepare_changeset(changeset, opts) do column = Keyword.get(opts, :column, :deleted_at) if changeset.action == :delete do changeset |> Ecto.Changeset.put_change(column, DateTime.utc_now()) |> Map.put(:action, :update) else changeset end end

def modify_query(query, opts) do column = Keyword.get(opts, :column, :deleted_at) from q in query, where: is_nil(field(q, ^column)) end

def before_action(:delete, _struct, opts), do: :ok, nil # prevent actual delete def before_action(, struct, opts), do: :ok, struct def after_action(, _, _), do: nil end


Ecto returns :error, changeset. But what about validation errors vs. database constraint errors vs. connection errors? Uni normalizes all Ecto errors into a standard Uni.Error.t() structure.

test/uni_ecto_plugin/soft_delete_test.exs

defmodule UniEctoPlugin.SoftDeleteTest do
  use ExUnit.Case, async: true
  alias Ecto.Adapters.SQL.Sandbox
  # Setup a test repo (see full example in Appendix)

defmodule TestRepo do use Ecto.Repo, otp_app: :uni_ecto_plugin, adapter: Ecto.Adapters.Postgres end

defmodule User do use Ecto.Schema use UniEctoPlugin.SoftDelete uni ecto plugin

schema "users" do
  field :name, :string
  timestamps()
end

end

setup do :ok = Sandbox.checkout(TestRepo) end

test "soft_delete/2 sets deleted_at" do :ok, user = %Username: "Jane" |> TestRepo.insert() assert user.deleted_at == nil :ok, deleted_user = User.soft_delete(user, TestRepo) refute is_nil(deleted_user.deleted_at) assert User.deleted?(deleted_user) end

test "restore/2 clears deleted_at" do user = %Username: "John", deleted_at: DateTime.utc_now() :ok, restored = User.restore(user, TestRepo) assert is_nil(restored.deleted_at) refute User.deleted?(restored) end end step = Ecto

case UserRegistration.run(%email: "alice@example.com", name: "Alice") do
  :ok, %update_role: user -> 
    IO.inspect(user, label: "Registered user")
  :error, step_name, error, _ctx ->
    IO.puts("Failed at step #step_name: #inspect(error)")
end

Key observation: Each step’s result is automatically stored under its step name (:insert_user, :update_role) inside the pipeline context. The named access (ctx.data.insert_user) makes dependencies explicit and traceable.


Uni Ecto Plugin is an Elixir library plugin that adds Uni (a hypothetical or project-specific) integration to Ecto, Elixir’s database wrapper and query generator. It provides adapter-like helpers, custom types, and query conveniences so Ecto schemas and queries work smoothly with Uni-specific data shapes, behaviors, or remote datastore features.

The plugin introduces a set of generic "Behaviors" that external services must conform to. Works identically to insert , but for an existing record

Let's assume you are using the popular triplex library (which implements the uni pattern) or the unifex approach. For this guide, we will use a generic setup based on the uni_ecto_plugin pattern.