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
|
cardinality = relationship.cardinality
|
||||||
|
|
||||||
query =
|
loads =
|
||||||
query
|
if Map.has_key?(relationship, :manual) && relationship.manual do
|
||||||
|> Ash.Query.new()
|
field
|
||||||
|> Ash.Query.set_tenant(tenant)
|
else
|
||||||
|> Ash.Query.for_read(
|
query =
|
||||||
relationship.read_action ||
|
query
|
||||||
Ash.Resource.Info.primary_action!(relationship.destination, :read).name,
|
|> Ash.Query.new()
|
||||||
opts[:args]
|
|> 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 =
|
loaded =
|
||||||
case loaded do
|
case loaded do
|
||||||
|
|
|
@ -613,4 +613,57 @@ defmodule AshGraphql.ReadTest do
|
||||||
variables: %{"id" => post.id}
|
variables: %{"id" => post.id}
|
||||||
)
|
)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -58,6 +58,35 @@ defmodule AfterActionRaiseResourceError do
|
||||||
end
|
end
|
||||||
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
|
defmodule AshGraphql.Test.Post do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
|
@ -317,5 +346,9 @@ defmodule AshGraphql.Test.Post do
|
||||||
source_attribute_on_join_resource: :post_id,
|
source_attribute_on_join_resource: :post_id,
|
||||||
destination_attribute_on_join_resource: :tag_id
|
destination_attribute_on_join_resource: :tag_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
has_many :related_posts, AshGraphql.Test.Post do
|
||||||
|
manual(RelatedPosts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue