Skip to content

fix: resolve actor/context templates in through relationship filters#789

Merged
zachdaniel merged 1 commit into
ash-project:mainfrom
barnabasJ:fix/788-through-relationship-template-filters
Jul 7, 2026
Merged

fix: resolve actor/context templates in through relationship filters#789
zachdaniel merged 1 commit into
ash-project:mainfrom
barnabasJ:fix/788-through-relationship-template-filters

Conversation

@barnabasJ

Copy link
Copy Markdown
Contributor

Problem

Fixes #788.

When a has_many relationship carries a filter that uses a ^context/1 or ^actor/1 template, and that relationship is used inside a has_many ... through relationship, loading the through relationship fails:

** (RuntimeError) Unsupported expression in Elixir.AshPostgres.SqlImplementation query:
{:_context, :sample_context}

The intermediate relationship's filter was applied via Ash.Query.do_filter without filling the template, so the raw template ({:_context, :sample_context}) was handed to the SQL implementation, which cannot compile it. The same class of bug affected ^actor/1, ^arg/1 and ^tenant/0 templates.

Fix

Fill ^actor/^context/^arg/^tenant templates before the intermediate relationship filter is compiled into SQL, in both through code paths in lib/data_layer.ex (the recursive build_through_queries/4 used for 3+ hop paths, and the inline path used for 2-hop / many_to_many).

This mirrors how a directly loaded relationship filter is hydrated in Ash.Actions.Read.Relationships: actor/args/tenant come from the source query, while the context is taken from the query the filter is being applied to (after its set_context). As a result, loading a through relationship resolves templates identically to loading each hop directly.

Tests

Added intermediate relationships with ^context and ^actor filters on the Through.School test resource, plus through relationships using them, covering both the 3-hop (build_through_queries) and 2-hop (inline) paths. New tests in test/through_relationships_test.exs assert:

  • the ^context/^actor templates no longer raise, and
  • the ^actor template resolves to the actor's value and filters the through relationship correctly.

Full suite: 832 passing, mix format clean, mix ash_postgres.generate_migrations --check clean.

🤖 Generated with Claude Code

Relationship filters used by `has_many ... through` relationships that
reference `^actor/1`, `^context/1`, `^arg/1` or `^tenant/0` templates were
applied without filling the template, so the raw template (e.g.
`{:_context, :sample_context}`) was handed to the SQL implementation and
raised "Unsupported expression in ... query".

Fill the templates before compiling the filter into SQL, mirroring how a
directly loaded relationship filter is hydrated: actor/args/tenant come
from the source query while the context is taken from the query the filter
is being applied to.

Fixes ash-project#788

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zachdaniel
zachdaniel merged commit a780a5c into ash-project:main Jul 7, 2026
110 of 121 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.

^context/1 and ^actor/1 templates are not supported in relationship filters used by has_many ... through

2 participants