Policies for updates can generate invalid ecto code when loading other resources
- Dominant language
- Elixir
- Stars
- 2.5k
- Forks
- 422
- Avg merge
- 23h 26m
- Merged PRs (30d)
- 46
Description
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
### AI Policy
- [x] I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.
### Versions
When upgrading from 3.5.23 to 3.5.34
### Operating system
ubuntu 24, macos
### Current Behavior
I have a policy that requires loading a related resource to check some conditions. This generates an invalid ecto query that tries to insert a subquery into the `from` of an `update_all` query.
In our case:
We have some resource A, eg Organisations, that has a `has_many` relationship with some other resource B, eg UserOrganisations,
Previously we had a policy that uses an expr( ) filter to check if an actor is an admin;
```
policy action(:update) do
authorize_if expr(exists(user_organisations, user_id == ^actor(:id) and role == "admin"))
end
```
When bumping ash, this seems to generate invalid ecto-- it tries to insert a subquery in the `from` of an `update_all`
```
* ** (Ecto.QueryError) `update_all` does not allow subqueries in `from` in query:
from o0 in subquery(from o0 in Accounts.Organisation,
as: 0,
left_join: u1 in subquery(from u0 in Accounts.UserOrganisation,
as: 500,
where: is_nil(
type(
as(500).archived_at,
{:parameterized,
{Ash.Type.UtcDatetimeUsec.EctoType,
precision: :microsecond, cast_dates_as: :start_of_day, timezone: :utc}}
)
),
```
For us this also occurs in a similar way with a forbid_unless statement
```
forbid_unless relates_to_actor_via([:user_organisation, :user])
```
where the user_organisation again is generating a subquery.
This is the only similar kinda situation with ecto:
https://groups.google.com/g/elixir-ecto/c/4rjWQoyYhmI/m/9Vz14hUfAgAJ
### Reproduction
Create a policy on a resource that requires loading another resource. So a resource A with has_many B. Have a policy that tries to do something on A depending on some property in B, eg if B is an admin.
### Expected Behavior
Ash should not generate invalid ecto code or at least fail to compile? If it tries to insert a subquery in from, should that not become a seperate query before somehow?
Contributor guide
Research direction
Start by running the described policy reproduction for a resource with a has_many relationship and inspect the generated update_all query, especially the subquery in from. Trace the update policy and related-resource loading path; done means neither expr(exists(...)) nor forbid_unless relates_to_actor_via(...) produces invalid Ecto code, with regression coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir
- Domain
- authorization, backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100