From 3778c5259c42159e276f3810d4f5d430d573636d Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 9 Jan 2026 05:26:04 +0100 Subject: [PATCH] Pass actor parameter to member email validation Extract actor from changeset context and pass it to Ash.read and Ash.load calls in email uniqueness validation. --- .../validations/email_not_used_by_other_user.ex | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/mv/membership/member/validations/email_not_used_by_other_user.ex b/lib/mv/membership/member/validations/email_not_used_by_other_user.ex index a14bc0b..649493b 100644 --- a/lib/mv/membership/member/validations/email_not_used_by_other_user.ex +++ b/lib/mv/membership/member/validations/email_not_used_by_other_user.ex @@ -29,7 +29,8 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do def validate(changeset, _opts, _context) do email_changing? = Ash.Changeset.changing_attribute?(changeset, :email) - linked_user_id = get_linked_user_id(changeset.data) + actor = Map.get(changeset.context || %{}, :actor) + linked_user_id = get_linked_user_id(changeset.data, actor) is_linked? = not is_nil(linked_user_id) # Only validate if member is already linked AND email is changing @@ -38,19 +39,21 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do if should_validate? do new_email = Ash.Changeset.get_attribute(changeset, :email) - check_email_uniqueness(new_email, linked_user_id) + check_email_uniqueness(new_email, linked_user_id, actor) else :ok end end - defp check_email_uniqueness(email, exclude_user_id) do + defp check_email_uniqueness(email, exclude_user_id, actor) do query = Mv.Accounts.User |> Ash.Query.filter(email == ^email) |> maybe_exclude_id(exclude_user_id) - case Ash.read(query) do + opts = if actor, do: [actor: actor], else: [] + + case Ash.read(query, opts) do {:ok, []} -> :ok @@ -65,8 +68,10 @@ defmodule Mv.Membership.Member.Validations.EmailNotUsedByOtherUser do defp maybe_exclude_id(query, nil), do: query defp maybe_exclude_id(query, id), do: Ash.Query.filter(query, id != ^id) - defp get_linked_user_id(member_data) do - case Ash.load(member_data, :user) do + defp get_linked_user_id(member_data, actor) do + opts = if actor, do: [actor: actor], else: [] + + case Ash.load(member_data, :user, opts) do {:ok, %{user: %{id: id}}} -> id _ -> nil end