Skip to content

Commit

Permalink
Allow to configure Originator Field Options (#115)
Browse files Browse the repository at this point in the history
also adds better support for :binary_id UUIDs
  • Loading branch information
maennchen committed Dec 4, 2020
1 parent b81dd32 commit 1e7dd40
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 8 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
- run: docker-compose run paper_trail mix test test/paper_trail
- run: docker-compose run paper_trail mix test test/version
- run: docker-compose run paper_trail mix test test/uuid
- run: docker-compose run paper_trail mix test test/uuid_with_custom_name

workflows:
version: 2
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,26 @@ YES! Make sure you do the steps above.
If you are using UUID or another type for your primary keys, you can configure
the PaperTrail.Version schema to use it.

##### Example Config

```elixir
config :paper_trail, item_type: Ecto.UUID,
originator_type: Ecto.UUID
originator_type: Ecto.UUID,
originator_relationship_options: [references: :uuid]
```

###### Example User

```elixir
defmodule Acme.User do
use Ecto.Schema

@primary_key {:uuid, :binary_id, autogenerate: true}
schema "users" do
field :email, :string

timestamps()
end
```

Remember to edit the types accordingly in the generated migration.
Expand Down
10 changes: 9 additions & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use Mix.Config

config :paper_trail, ecto_repos: [PaperTrail.Repo, PaperTrail.UUIDRepo]
config :paper_trail, ecto_repos: [PaperTrail.Repo, PaperTrail.UUIDRepo, PaperTrail.UUIDWithCustomNameRepo]

config :paper_trail, repo: PaperTrail.Repo, originator: [name: :user, model: User]

Expand All @@ -20,4 +20,12 @@ config :paper_trail, PaperTrail.UUIDRepo,
hostname: System.get_env("PG_HOST"),
poolsize: 10

config :paper_trail, PaperTrail.UUIDWithCustomNameRepo,
adapter: Ecto.Adapters.Postgres,
username: System.get_env("POSTGRES_USER"),
password: System.get_env("POSTGRES_PASSWORD"),
database: "paper_trail_uuid_with_custom_name_test",
hostname: System.get_env("PG_HOST"),
poolsize: 10

config :logger, level: :warn
9 changes: 6 additions & 3 deletions lib/paper_trail/serializer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ defmodule PaperTrail.Serializer do
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
%{id: id} -> id
model when is_struct(model) -> get_model_id(originator_ref)
end,
origin: options[:origin],
meta: options[:meta]
Expand All @@ -46,7 +47,8 @@ defmodule PaperTrail.Serializer do
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
%{id: id} -> id
model when is_struct(model) -> get_model_id(originator_ref)
end,
origin: options[:origin],
meta: options[:meta]
Expand All @@ -66,7 +68,8 @@ defmodule PaperTrail.Serializer do
originator_id:
case originator_ref do
nil -> nil
_ -> originator_ref |> Map.get(:id)
%{id: id} -> id
model when is_struct(model) -> get_model_id(originator_ref)
end,
origin: options[:origin],
meta: options[:meta]
Expand Down
8 changes: 5 additions & 3 deletions lib/version.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ defmodule PaperTrail.Version do
belongs_to(
PaperTrail.RepoClient.originator()[:name],
PaperTrail.RepoClient.originator()[:model],
define_field: false,
foreign_key: :originator_id,
type: Application.get_env(:paper_trail, :originator_type, :integer)
Keyword.merge(Application.get_env(:paper_trail, :originator_relationship_options, []),
define_field: false,
foreign_key: :originator_id,
type: Application.get_env(:paper_trail, :originator_type, :integer)
)
)
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule PaperTrail.UUIDWithCustomNameRepo.Migrations.CreateProjects do
use Ecto.Migration

def change do
create table(:projects, primary_key: false) do
add :uuid, :binary_id, primary_key: true
add :name, :string, null: false

timestamps()
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule PaperTrail.UUIDWithCustomNameRepo.Migrations.CreatePeople do
use Ecto.Migration

def change do
create table(:people, primary_key: false) do
add :uuid, :binary_id, primary_key: true
add :email, :string, null: false

timestamps()
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule PaperTrail.UUIDWithCustomNameRepo.Migrations.CreateVersions do
use Ecto.Migration

def change do
create table(:versions) do
add :event, :string, null: false, size: 10
add :item_type, :string, null: false
add :item_id, (if System.get_env("STRING_TEST") == nil, do: :binary_id, else: :string)
add :item_changes, :map, null: false
add :originator_id, references(:people, type: :binary_id, column: :uuid)
add :origin, :string, size: 50
add :meta, :map

add :inserted_at, :utc_datetime, null: false
end

create index(:versions, [:originator_id])
create index(:versions, [:item_id, :item_type])
create index(:versions, [:event, :item_type])
create index(:versions, [:item_type, :inserted_at])
end
end
4 changes: 4 additions & 0 deletions test/support/repos.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ defmodule PaperTrail.UUIDRepo do
use Ecto.Repo, otp_app: :paper_trail, adapter: Ecto.Adapters.Postgres
end

defmodule PaperTrail.UUIDWithCustomNameRepo do
use Ecto.Repo, otp_app: :paper_trail, adapter: Ecto.Adapters.Postgres
end

defmodule User do
use Ecto.Schema

Expand Down
36 changes: 36 additions & 0 deletions test/support/uuid_with_custom_name_models.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Project do
use Ecto.Schema

import Ecto.Changeset

@primary_key {:uuid, :binary_id, autogenerate: true}
schema "projects" do
field(:name, :string)

timestamps()
end

def changeset(model, params \\ %{}) do
model
|> cast(params, [:name])
|> validate_required([:name])
end
end

defmodule Person do
use Ecto.Schema
import Ecto.Changeset

@primary_key {:uuid, :binary_id, autogenerate: true}
schema "people" do
field(:email, :string)

timestamps()
end

def changeset(model, params \\ %{}) do
model
|> cast(params, [:email])
|> validate_required([:email])
end
end
2 changes: 2 additions & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ Mix.Task.run("ecto.migrate")

PaperTrail.Repo.start_link()
PaperTrail.UUIDRepo.start_link()
PaperTrail.UUIDWithCustomNameRepo.start_link()

Code.require_file("test/support/multi_tenant_helper.exs")
Code.require_file("test/support/simple_models.exs")
Code.require_file("test/support/strict_models.exs")
Code.require_file("test/support/uuid_models.exs")
Code.require_file("test/support/uuid_with_custom_name_models.exs")

ExUnit.configure(seed: 0)

Expand Down
48 changes: 48 additions & 0 deletions test/uuid/uuid_with_custom_name_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule PaperTrailTest.UUIDWithCustomNameTest do
use ExUnit.Case
import PaperTrail.RepoClient, only: [repo: 0]
alias PaperTrail.Version
import Ecto.Query

setup_all do
Application.put_env(:paper_trail, :repo, PaperTrail.UUIDWithCustomNameRepo)
Application.put_env(:paper_trail, :originator, name: :originator, model: Person)
Application.put_env(:paper_trail, :originator_type, Ecto.UUID)
Application.put_env(:paper_trail, :originator_relationship_options, references: :uuid)

Application.put_env(
:paper_trail,
:item_type,
if(System.get_env("STRING_TEST") == nil, do: Ecto.UUID, else: :string)
)

Code.eval_file("lib/paper_trail.ex")
Code.eval_file("lib/version.ex")

repo().delete_all(Version)
repo().delete_all(Person)
repo().delete_all(Project)
:ok
end

describe "PaperTrailTest.UUIDWithCustomNameTest" do
test "handles originators with a UUID primary key" do
person =
%Person{}
|> Person.changeset(%{email: "admin@example.com"})
|> repo().insert!

%Project{}
|> Project.changeset(%{name: "Interesting Stuff"})
|> PaperTrail.insert!(originator: person)

version =
Version
|> last
|> repo().one
|> repo().preload(:originator)

assert version.originator == person
end
end
end

0 comments on commit 1e7dd40

Please sign in to comment.