mirror of
https://github.com/ash-project/ash_graphql.git
synced 2024-09-19 21:03:09 +12:00
improvement: support manual relationships (#66)
This commit is contained in:
parent
e826534bce
commit
d89a14175c
3 changed files with 103 additions and 10 deletions
|
@ -235,17 +235,24 @@ defmodule AshGraphql.Dataloader do
|
|||
|
||||
cardinality = relationship.cardinality
|
||||
|
||||
query =
|
||||
query
|
||||
|> Ash.Query.new()
|
||||
|> Ash.Query.set_tenant(tenant)
|
||||
|> Ash.Query.for_read(
|
||||
relationship.read_action ||
|
||||
Ash.Resource.Info.primary_action!(relationship.destination, :read).name,
|
||||
opts[:args]
|
||||
)
|
||||
loads =
|
||||
if Map.has_key?(relationship, :manual) && relationship.manual do
|
||||
field
|
||||
else
|
||||
query =
|
||||
query
|
||||
|> Ash.Query.new()
|
||||
|> Ash.Query.set_tenant(tenant)
|
||||
|> Ash.Query.for_read(
|
||||
relationship.read_action ||
|
||||
Ash.Resource.Info.primary_action!(relationship.destination, :read).name,
|
||||
opts[:args]
|
||||
)
|
||||
|
||||
loaded = source.api.load!(records, [{field, query}], api_opts || [])
|
||||
{field, query}
|
||||
end
|
||||
|
||||
loaded = source.api.load!(records, [loads], api_opts || [])
|
||||
|
||||
loaded =
|
||||
case loaded do
|
||||
|
|
|
@ -613,4 +613,57 @@ defmodule AshGraphql.ReadTest do
|
|||
variables: %{"id" => post.id}
|
||||
)
|
||||
end
|
||||
|
||||
test "manual relationships can be read" do
|
||||
tag =
|
||||
AshGraphql.Test.Tag
|
||||
|> Ash.Changeset.for_create(
|
||||
:create,
|
||||
name: "My Tag"
|
||||
)
|
||||
|> AshGraphql.Test.Api.create!()
|
||||
|
||||
post_1 =
|
||||
AshGraphql.Test.Post
|
||||
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|
||||
|> Ash.Changeset.manage_relationship(
|
||||
:tags,
|
||||
[tag],
|
||||
on_no_match: {:create, :create_action},
|
||||
on_lookup: :relate
|
||||
)
|
||||
|> AshGraphql.Test.Api.create!()
|
||||
|
||||
AshGraphql.Test.Post
|
||||
|> Ash.Changeset.for_create(:create, text: "bar", published: true)
|
||||
|> Ash.Changeset.manage_relationship(
|
||||
:tags,
|
||||
[tag],
|
||||
on_no_match: {:create, :create_action},
|
||||
on_lookup: :relate
|
||||
)
|
||||
|> AshGraphql.Test.Api.create!()
|
||||
|
||||
doc = """
|
||||
query ($id: ID!) {
|
||||
getPost(id: $id) {
|
||||
text
|
||||
relatedPosts {
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
data: %{
|
||||
"getPost" => %{
|
||||
"relatedPosts" => [%{"text" => "bar"}],
|
||||
"text" => "foo"
|
||||
}
|
||||
}
|
||||
}} ==
|
||||
Absinthe.run(doc, AshGraphql.Test.Schema, variables: %{"id" => post_1.id})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,6 +58,35 @@ defmodule AfterActionRaiseResourceError do
|
|||
end
|
||||
end
|
||||
|
||||
defmodule RelatedPosts do
|
||||
@moduledoc false
|
||||
use Ash.Resource.ManualRelationship
|
||||
require Ash.Query
|
||||
|
||||
def load(posts, _opts, %{api: api}) do
|
||||
posts = api.load!(posts, :tags)
|
||||
|
||||
{
|
||||
:ok,
|
||||
posts
|
||||
|> Enum.map(fn post ->
|
||||
tag_ids =
|
||||
post.tags
|
||||
|> Enum.map(& &1.id)
|
||||
|
||||
other_posts =
|
||||
AshGraphql.Test.Post
|
||||
|> Ash.Query.filter(tags.id in ^tag_ids)
|
||||
|> Ash.Query.filter(id != ^post.id)
|
||||
|> api.read!()
|
||||
|
||||
{post.id, other_posts}
|
||||
end)
|
||||
|> Map.new()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule AshGraphql.Test.Post do
|
||||
@moduledoc false
|
||||
|
||||
|
@ -317,5 +346,9 @@ defmodule AshGraphql.Test.Post do
|
|||
source_attribute_on_join_resource: :post_id,
|
||||
destination_attribute_on_join_resource: :tag_id
|
||||
)
|
||||
|
||||
has_many :related_posts, AshGraphql.Test.Post do
|
||||
manual(RelatedPosts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue