将聚合字段添加到 elixir graphql
Adding aggregate fields to elixir graphql
我正在使用苦艾酒和长生不老药 (phoenix 1.3)。我有一个包含用户、帖子和点赞的博客应用程序,点赞是通过用户和帖子之间的多对多关系加入的。
schema "users" do
field :email, :string
field :handle, :string
many_to_many :liked_posts, MyApp.Content.Post, join_through: "likes"
end
schema "posts" do
field :title, :string
field :content, :string
many_to_many :liking_users, MyApp.Accounts.User, join_through: "likes"
end
schema "likes" do
belongs_to :user, MyApp.Accounts.User
belongs_to :post, MyApp.Content.Post
end
假设我想在后端而不是前端聚合它们。我希望 :liked_by
只是所有存在的喜欢的计数,更像是 field :likes, :int
,这样我就可以得到这样的回复:
{
"data": {
"post" : {
"title" : "Title",
"content" : "This is the content",
"likes" : 7
}
}
}
我的对象应该是什么样子?我想做这样的事情:
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: assoc(:liking_users, fn query, id, _ ->
query |> from like in MyApp.Content.Like, where: like.post_id == ^id, select: count("*")
)
end
编辑 #1: 更具体地说,我想知道如何在苦艾酒对象中参数化匿名函数。我可以轻松地将对象设为 return 非参数化值:
field :somenumber, :integer, resolve: fn (_,_) -> {:ok, 15} end
但是像这样添加一个参数
field :somenumber, :integer, resolve: fn (foo,_) -> {:ok, foo} end
return如下:
...
"somenumber": {},
...
如何传入对象的 ID,或隐式关联的查询?
编辑#2:我找到了解决这个问题的方法,但感觉很老套。
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: fn (_,_,resolution) ->
{:ok, Post.getLikeCount(resolution.source.id) }
end
end
按照@mudasobwa 的建议,我有了这个解决方案:
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: fn (query,_,_) ->
Post.getLikeCount(query.id)
end
end
resolution
,解析器的 arity 3 匿名函数的第三个参数,是一个 Absinthe.Resolution
对象。 resolution.source
是MyApp.Content.Post
类型,其中id
指的是Post。
然后我刚刚在 Post.ex 中添加了一个名为 getLikeCount/1
的函数来获取点赞数。
def getLikeCount (post_id) do
query =
from l in MyApp.Content.Likes,
where: l.post_id == ^post_id,
select: count("*")
case Repo.one(query) do
nil -> {:error, "Error getting like count for post #{post_id}"}
likes -> {:ok, likes}
end
end
我正在使用苦艾酒和长生不老药 (phoenix 1.3)。我有一个包含用户、帖子和点赞的博客应用程序,点赞是通过用户和帖子之间的多对多关系加入的。
schema "users" do
field :email, :string
field :handle, :string
many_to_many :liked_posts, MyApp.Content.Post, join_through: "likes"
end
schema "posts" do
field :title, :string
field :content, :string
many_to_many :liking_users, MyApp.Accounts.User, join_through: "likes"
end
schema "likes" do
belongs_to :user, MyApp.Accounts.User
belongs_to :post, MyApp.Content.Post
end
假设我想在后端而不是前端聚合它们。我希望 :liked_by
只是所有存在的喜欢的计数,更像是 field :likes, :int
,这样我就可以得到这样的回复:
{
"data": {
"post" : {
"title" : "Title",
"content" : "This is the content",
"likes" : 7
}
}
}
我的对象应该是什么样子?我想做这样的事情:
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: assoc(:liking_users, fn query, id, _ ->
query |> from like in MyApp.Content.Like, where: like.post_id == ^id, select: count("*")
)
end
编辑 #1: 更具体地说,我想知道如何在苦艾酒对象中参数化匿名函数。我可以轻松地将对象设为 return 非参数化值:
field :somenumber, :integer, resolve: fn (_,_) -> {:ok, 15} end
但是像这样添加一个参数
field :somenumber, :integer, resolve: fn (foo,_) -> {:ok, foo} end
return如下:
...
"somenumber": {},
...
如何传入对象的 ID,或隐式关联的查询?
编辑#2:我找到了解决这个问题的方法,但感觉很老套。
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: fn (_,_,resolution) ->
{:ok, Post.getLikeCount(resolution.source.id) }
end
end
按照@mudasobwa 的建议,我有了这个解决方案:
object :post do
field :id, :integer
field :title, :string
field :content, :string
field :likes, :integer, resolve: fn (query,_,_) ->
Post.getLikeCount(query.id)
end
end
resolution
,解析器的 arity 3 匿名函数的第三个参数,是一个 Absinthe.Resolution
对象。 resolution.source
是MyApp.Content.Post
类型,其中id
指的是Post。
然后我刚刚在 Post.ex 中添加了一个名为 getLikeCount/1
的函数来获取点赞数。
def getLikeCount (post_id) do
query =
from l in MyApp.Content.Likes,
where: l.post_id == ^post_id,
select: count("*")
case Repo.one(query) do
nil -> {:error, "Error getting like count for post #{post_id}"}
likes -> {:ok, likes}
end
end