Skip to content

feat: add eager_validate? option to manage_relationship/4#2663

Merged
zachdaniel merged 1 commit intoash-project:mainfrom
nallwhy:feat/manage-relationship-eager-validate
Apr 7, 2026
Merged

feat: add eager_validate? option to manage_relationship/4#2663
zachdaniel merged 1 commit intoash-project:mainfrom
nallwhy:feat/manage-relationship-eager-validate

Conversation

@nallwhy
Copy link
Copy Markdown
Contributor

@nallwhy nallwhy commented Apr 7, 2026

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

Summary

  • Add eager_validate? boolean option to Ash.Changeset.manage_relationship/4
  • When true, automatically infers the domain from the related resource's domain configuration
  • Mirrors the eager_check? / eager_check_with pattern introduced for identities in feat: leverage resource domain for eager/pre checking #1040

Closes #1074

Copilot AI review requested due to automatic review settings April 7, 2026 00:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an eager_validate? convenience option to Ash.Changeset.manage_relationship/4 to enable eager relationship existence validation without explicitly providing a domain, by inferring the domain from the destination (related) resource—mirroring the identity eager-check ergonomics introduced in #1040.

Changes:

  • Add eager_validate?: boolean to manage_relationship/4 options schema and documentation.
  • When eager_validate?: true and eager_validate_with is not provided, infer eager_validate_with from Ash.Resource.Info.domain(destination), raising if missing.
  • Add a unit test covering eager validation via eager_validate? for many-to-many upsert/relate behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
lib/ash/changeset/changeset.ex Introduces the new option and domain inference logic inside manage_relationship/4.
test/changeset/changeset_test.exs Adds coverage asserting eager validation works when using eager_validate?: true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 5609 to +5615
"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."
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new eager_validate? option doc doesn’t mention that it will raise when the destination resource has no configured domain (and that eager_validate_with can be used instead / takes precedence). Consider updating the option docs to reflect the actual behavior so callers know when/why it errors.

Suggested change
"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."
"Validates that any referenced entities exist *before* the action is being performed, using the provided domain for the read. Takes precedence over `eager_validate?`."
],
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. If the related resource has no configured domain, this raises unless `eager_validate_with` is provided."

Copilot uses AI. Check for mistakes.
Comment on lines +6027 to +6041
{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
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyword_opts is generated before opts.meta is augmented with :inputs_was_list? (5983-5987), but in the eager_validate? branch you regenerate keyword_opts after modifying opts. This makes the stored options inconsistent depending on whether eager_validate? is set, and can affect later error-path behavior that depends on opts[:meta][:inputs_was_list?] (see Ash.Actions.ManagedRelationships.set_error_path/4). Consider moving the to_options/1 call to after the opts.meta update (and avoid conditionally regenerating it here) so all calls get consistent meta in the stored relationship opts.

Copilot uses AI. Check for mistakes.
Comment on lines +6031 to +6035
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
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new branch raises when eager_validate?: true is used and the destination resource has no configured domain. There are similar tests for identity eager_check domain inference errors; adding a regression test for this raise would help prevent accidental behavior changes and ensure the error message stays stable.

Copilot uses AI. Check for mistakes.
@zachdaniel zachdaniel merged commit 7676f37 into ash-project:main Apr 7, 2026
48 of 49 checks passed
@zachdaniel
Copy link
Copy Markdown
Contributor

🚀 Thank you for your contribution! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add domain-less eager checking also to Ash.Changeset.manage_relationship/4

3 participants