ash-project / ash-project/ash

before_action hooks cannot add loads or calculations during read actions

Open
#2,174 3 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

### Versions

Ash: master
Elixir: 1.18.3
Erlang/OTP 27

### Operating system

Mac

### Current Behavior

When using before_action hooks in read actions, attempting to add new loads (relationships) or calculations to the query does not work as expected. The loads and calculations added during before_action
are not properly processed in the read flow.

- Relationships loaded via Ash.Query.load/2 in a before_action callback are ignored
- Calculations added via Ash.Query.calculate/4 in a before_action callback are not executed

### Reproduction

Examples

1. Loading relationships in before_action:
```elixir
read :read_with_authors_before_action do
prepare(
before_action(fn query, _context ->
Ash.Query.load(query, [:author1, :author2])
end)
)
end
```

2. Adding calculations in before_action:
```elixir
read :read_with_calculation_before_action do
prepare(
before_action(fn query, _context ->
Ash.Query.calculate(
query,
:title_and_contents,
:string,
expr(title <> " - " <> contents)
)
end)
)
end
```

Here is a patch to `test/actions/read_test.exs` that showcases the bug.
```elixir
diff --git a/test/actions/read_test.exs b/test/actions/read_test.exs
index 9d450f33..42f1137b 100644
--- a/test/actions/read_test.exs
+++ b/test/actions/read_test.exs
@@ -76,6 +76,27 @@ defmodule Ash.Test.Actions.ReadTest do
prepare(build(load: [:author1, :author2]))
end

+ read :read_with_authors_before_action do
+ prepare(
+ before_action(fn query, _context ->
+ Ash.Query.load(query, [:author1, :author2])
+ end)
+ )
+ end
+
+ read :read_with_calculation_before_action do
+ prepare(
+ before_action(fn query, _context ->
+ Ash.Query.calculate(
+ query,
+ :title_and_contents,
+ :string,
+ expr(title <> " - " <> contents)
+ )
+ end)
+ )
+ end
+
read :read_with_unknown_intpus do
skip_unknown_inputs :*
end
@@ -212,6 +233,16 @@ defmodule Ash.Test.Actions.ReadTest do
fetched_post = Ash.get!(Post, post.id, action: :read_with_authors)
assert ^author1 = strip_metadata(fetched_post.author1)
end
+
+ test "before_action should be able to load relationships", %{post: post, author1: author1} do
+ fetched_post = Ash.get!(Post, post.id, action: :read_with_authors_before_action)
+ assert ^author1 = strip_metadata(fetched_post.author1)
+ end
+
+ test "before_action should be able to add calculations", %{post: post} do
+ fetched_post = Ash.get!(Post, post.id, action: :read_with_calculation_before_action)
+ assert "test - yeet" = fetched_post.calculations.title_and_contents
+ end
end

describe "Ash.get!/3" do
```

### Expected Behavior

- before_action hooks should be able to dynamically add loads and calculations to queries
- These dynamically added loads/calculations should be properly processed in the read pipeline
- The dynamically added loads/calculation should be authorized properly

Contributor guide

Open the contributing guide

Research direction

Start with the reproduction and regression cases in test/actions/read_test.exs, then run the read-action tests to observe the failures. Trace how before_action updates are processed in the read flow; done means relationship loads and calculations added there are executed and authorized, with the new assertions passing.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.