From b52da94b3218071b071e86bf5fb7aa2afbf8a2d3 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 29 Jan 2023 18:20:59 -0500 Subject: [PATCH] fix: properly convert to/from ecto, only when necessary --- lib/data_layer.ex | 37 +++++++++++++++++++++++++++++++++---- mix.lock | 2 +- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 422f15e..01e6ec1 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1158,28 +1158,57 @@ defmodule AshPostgres.DataLayer do defp from_ecto({:ok, result}), do: {:ok, from_ecto(result)} defp from_ecto({:error, _} = other), do: other + defp from_ecto(nil), do: nil + + defp from_ecto(value) when is_list(value) do + Enum.map(value, &from_ecto/1) + end + defp from_ecto(%resource{} = record) do empty = struct(resource) resource |> Ash.Resource.Info.relationships() |> Enum.reduce(record, fn relationship, record -> - Map.put(record, relationship.name, Map.get(empty, relationship.name)) + case Map.get(record, relationship.name) do + %Ecto.Association.NotLoaded{} -> + Map.put(record, relationship.name, Map.get(empty, relationship.name)) + + value -> + Map.put(record, relationship.name, from_ecto(value)) + end end) end defp from_ecto(other), do: other + defp to_ecto(nil), do: nil + + defp to_ecto(value) when is_list(value) do + Enum.map(value, &to_ecto/1) + end + defp to_ecto(%resource{} = record) do resource |> Ash.Resource.Info.relationships() |> Enum.reduce(record, fn relationship, record -> - Map.put(record, relationship.name, %Ecto.Association.NotLoaded{ - __cardinality__: relationship.cardinality - }) + value = + case Map.get(record, relationship.name) do + %Ash.NotLoaded{} -> + %Ecto.Association.NotLoaded{ + __cardinality__: relationship.cardinality + } + + value -> + to_ecto(value) + end + + Map.put(record, relationship.name, value) end) end + defp to_ecto(other), do: other + defp add_check_constraints(changeset, resource) do resource |> AshPostgres.DataLayer.Info.check_constraints() diff --git a/mix.lock b/mix.lock index 637752a..b3ec207 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "2.5.10", "edd51600f6db3e27888b8e3d4c4194b1f12aee7abe4f1d77594791cacfc85571", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 0.3.0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a8c9cdeb6f28d77389b5c185f00afa461225b14ac6289e102133930af505a7d0"}, + "ash": {:hex, :ash, "2.5.11", "eeadeba560681d53be5438a15434c121f0dc8b108cdf05e975a40fe809865df4", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 0.3.0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf2b5e337650b7bdc805af2a6038f5126a344c0439320606f5f8db9e11962071"}, "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, "comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},