fix: properly await tasks from lazy loading multiple relationships

This commit is contained in:
Zach Daniel 2024-09-04 10:32:34 -04:00
parent 745aa6e85f
commit d144be692e
4 changed files with 63 additions and 3 deletions

View file

@ -42,7 +42,16 @@ defmodule Ash.Actions.Read.Relationships do
defp fetch_related_records(batch, records, acc \\ [])
defp fetch_related_records([], _records, acc) do
Ash.Actions.Read.AsyncLimiter.await_all(acc)
Enum.map(acc, fn
{a, b, %Task{} = task} ->
{a, b, Task.await(task, :infinity)}
%Task{} = task ->
Task.await(task, :infinity)
other ->
other
end)
end
defp fetch_related_records([first | rest], records, acc) do

View file

@ -330,6 +330,34 @@ defmodule Ash.Test.Actions.AsyncLoadTest do
end
end
test "it allows loading multiple lazy relationships" do
author =
Author
|> Ash.Changeset.for_create(:create, %{name: "zerg"})
|> Ash.create!()
post1 =
Post
|> Ash.Changeset.for_create(:create, %{title: "post1"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
Post
|> Ash.Changeset.for_create(:create, %{title: "post2"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
[author] =
Author
|> Ash.Query.load(posts: [:author])
|> Ash.Query.filter(posts.id == ^post1.id)
|> Ash.read!(authorize?: true)
author
|> Ash.load!([:posts, :latest_post])
|> Ash.load!([:posts, :latest_post], lazy?: true)
end
test "it allows loading many to many relationships" do
category1 =
Category

View file

@ -688,6 +688,31 @@ defmodule Ash.Test.Actions.LoadTest do
refute match?(%Ash.NotLoaded{}, author.latest_post)
end
test "you can load multiple relationships with `lazy?: true`" do
author =
Author
|> Ash.Changeset.for_create(:create, %{name: "zerg"})
|> Ash.create!()
Post
|> Ash.Changeset.for_create(:create, %{title: "post1"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
Post
|> Ash.Changeset.for_create(:create, %{title: "post2"})
|> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove)
|> Ash.create!()
[author] =
Author
|> Ash.Query.load([:posts, :latest_post])
|> Ash.read!(authorize?: true)
author =
Ash.load!(author, [:posts, :latest_post], lazy?: true)
end
test "loading something already loaded still loads it unless lazy?: true" do
author =
Author

View file

@ -137,8 +137,6 @@ defmodule Ash.Test.Policy.SimpleTest do
test "Ash.can? accepts a record to determine if it can be read", %{admin: admin, user: user} do
tweet = Ash.create!(Ash.Changeset.for_create(Tweet, :create), authorize?: false)
Logger.configure(level: :debug)
assert Ash.can?({tweet, :read}, admin)
refute Ash.can?({tweet, :read}, user)
end