From 8f79fcb59ddaef5a9542cec24f374a6e21ea5f3f Mon Sep 17 00:00:00 2001 From: Jesse Williams Date: Thu, 18 Jul 2024 13:37:31 -0700 Subject: [PATCH] fix: allow non-unique has_many source_attributes (#355) * fix: allow non-unique has_many source_attributes * fix composite primary key case --- lib/data_layer.ex | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 1602df4..b0676b6 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1044,9 +1044,43 @@ defmodule AshPostgres.DataLayer do {:ok, data_layer_query} -> source_values = Enum.map(root_data, &Map.get(&1, source_attribute)) + source_filter = + case source_pkey do + [] -> + Ecto.Query.dynamic([source], field(source, ^source_attribute) in ^source_values) + + [field] -> + values = Enum.map(root_data, &Map.get(&1, field)) + Ecto.Query.dynamic([source], field(source, ^field) in ^values) + + fields -> + Enum.reduce(root_data, nil, fn record, acc -> + row_match = + Enum.reduce(fields, nil, fn field, acc -> + if is_nil(acc) do + Ecto.Query.dynamic( + [source], + field(source, ^field) == ^Map.get(record, field) + ) + else + Ecto.Query.dynamic( + [source], + field(source, ^field) == ^Map.get(record, field) and ^acc + ) + end + end) + + if is_nil(acc) do + row_match + else + Ecto.Query.dynamic(^row_match or ^acc) + end + end) + end + data_layer_query = from(source in data_layer_query, - where: field(source, ^source_attribute) in ^source_values + where: ^source_filter ) if query.__ash_bindings__[:__order__?] do