diff --git a/lib/ash/changeset/changeset.ex b/lib/ash/changeset/changeset.ex index b4f081645..f46698bf4 100644 --- a/lib/ash/changeset/changeset.ex +++ b/lib/ash/changeset/changeset.ex @@ -5608,6 +5608,12 @@ defmodule Ash.Changeset do doc: "Validates that any referenced entities exist *before* the action is being performed, using the provided domain for the read." ], + eager_validate?: [ + type: :boolean, + default: false, + doc: + "Validates that any referenced entities exist *before* the action is being performed, using the domain configured on the related resource." + ], on_no_match: [ type: :any, default: :ignore, @@ -6018,6 +6024,22 @@ defmodule Ash.Changeset do add_error(changeset, error) relationship -> + {opts, keyword_opts} = + if opts.eager_validate? && !opts.eager_validate_with do + domain = Ash.Resource.Info.domain(relationship.destination) + + if !domain do + raise ArgumentError, + "Cannot use `eager_validate?: true` because #{inspect(relationship.destination)} " <> + "does not have a domain configured. Use `eager_validate_with: YourDomain` instead." + end + + new_opts = %{opts | eager_validate_with: domain} + {new_opts, ManageRelationshipOpts.to_options(new_opts)} + else + {opts, keyword_opts} + end + key = opts.value_is_key || changeset.resource diff --git a/test/changeset/changeset_test.exs b/test/changeset/changeset_test.exs index 4a295a886..d65e85f77 100644 --- a/test/changeset/changeset_test.exs +++ b/test/changeset/changeset_test.exs @@ -859,6 +859,30 @@ defmodule Ash.Test.Changeset.ChangesetTest do ) end + test "upsert with many_to_many relationships can eager validate with eager_validate?" do + Category + |> Ash.Changeset.for_create(:create, %{name: "foo"}) + |> Ash.create!() + + assert %{valid?: false, errors: [%Ash.Error.Query.NotFound{}]} = + Post + |> Ash.Changeset.new() + |> Ash.Changeset.manage_relationship(:categories, [%{name: "foo"}, %{name: "bar"}], + on_lookup: :relate, + eager_validate?: true, + use_identities: [:unique_name] + ) + + assert %{valid?: true} = + Post + |> Ash.Changeset.new() + |> Ash.Changeset.manage_relationship(:categories, [%{name: "foo"}], + on_lookup: :relate, + eager_validate?: true, + use_identities: [:unique_name] + ) + end + test "it creates related entities" do post1 = %{title: "title"} post2 = %{title: "title"}