1

在我的 phoenix 应用程序中,我在 Artist 和使用连接表实现的 Cause 模式之间存在多对多关系artists_causes。在我的 Artist 模式中,我有many_to_many :causes, Cause, join_through: "artists_causes",在我的 Cause 模式中,many_to_many :artists, Artist, join_through: "artists_causes" 我使用苦艾酒作为 graphql,在我的CauseTypes模块中,我实现了一个cause对象,如下所示

defmodule MyAppWeb.Schema.CauseTypes do
  @moduledoc """
  All types for causes
  """
  use Absinthe.Schema.Notation
  import Absinthe.Resolution.Helpers, only: [dataloader: 1, dataloader: 3]

  object :cause do
    field :id, :id
    field :artists, list_of(:artist), resolve: dataloader(Artists)
  end

  def dataloader do
    alias MyApp.{Artists, Causes}
    loader = Dataloader.new
    |> Dataloader.add_source(Causes, Causes.datasource())
    |> Dataloader.add_source(Artists, Artists.datasource())
  end

  def context(ctx) do
    Map.put(ctx, :loader, dataloader())
  end

  def plugins do
    [Absinthe.Middleware.Dataloader] ++ Absinthe.Plugin.defaults()
  end
end

据我了解,使用 Absinthe Dataloader,dataloader/1 是加载艺术家列表所需的。artists: #Ecto.Association.NotLoaded<association :artists is not loaded>但是,当我在 graphiql 中运行以下查询时,我无法从出现错误的原因中查询艺术家

query{
 causes{
  id
  artists {
            id
   }
 }
}

在处理多对多的关系时,我是否缺少任何一点点?

==========

更新

我更新了我的 list_causes 函数如下

def list_causes do    
   Repo.all(MyApp.Causes.Cause) 
end

def list_causes do
    Repo.all(from c in Cause,
    left_join: ac in "artists_causes", on: c.id == ac.cause_id,
    left_join: a in Artist, on: a.id == ac.artist_id,
    preload: [:artists]
    )
  end

并且,我现在收到FunctionClauseError at POST /graphiql\n\nException:\n\n ** (FunctionClauseError) no function clause matching in anonymous fn/3 in Absinthe.Resolution.Helpers.dataloader/1可能指向该Absinthe.Resolution.Helpers.dataloader/1方法的错误。我有导入的助手还有什么我可能会丢失的吗?

4

1 回答 1

0

我认为您必须先从 Ecto 手动预加载与艺术家的关系,然后再将其传递给 Absinthe。

例如,获取原因如下:

from(c in Cause,
  preload: [:artists],
  select: c
)
|> Repo.all()

额外的

我解决苦艾酒查询的方法。

在查询对象中,我传递解析器模块函数引用。

resolve(&App.Resolver.get_all_causes/2)

并使用解析器功能返回数据集

def get_all_causes(_params, _info) do
  {:ok,
   from(c in Cause,
     preload: [:artists],
     select: c
   )
   |> Repo.all()}
end
于 2019-10-15T10:51:18.293 回答