ash-project / ash-project/ash

Policies for updates can generate invalid ecto code when loading other resources

Open
#2,275 8 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.