【问题标题】:How do I use Absinthe Dataloader for many to many relationships如何使用 Absinthe Dataloader 处理多对多关系
【发布时间】:2020-02-10 05:11:35
【问题描述】:

在我的 phoenix 应用程序中,我在 Artist 和使用连接表 artists_causes 实现的 Cause 模式之间存在多对多关系。在我的艺术家模式中,我有many_to_many :causes, Cause, join_through: "artists_causes",在原因模式中我有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 是加载艺术家列表所需的。但是,当我在 graphiql 中运行以下查询时,我无法从出现错误 artists: #Ecto.Association.NotLoaded<association :artists is not loaded> 的原因中查询艺术家

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 方法。我已经导入了助手我还有什么可能遗漏的吗?

【问题讨论】:

    标签: graphql elixir phoenix-framework absinthe


    【解决方案1】:

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

    例如,fetch 原因如下:

    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
    

    【讨论】:

    • 嗨@TreeFolk,谢谢,我已按照您的建议进行了更新,现在收到错误(FunctionClauseError) no function clause matching in anonymous fn/3 in Absinthe.Resolution.Helpers.dataloader/1,它可能指向ResolutionHelpers 的某些内容,我是否缺少某些东西?
    • 不幸的是,我的回答是基于我自己对苦艾酒的体验,我没有使用 Dataloader。我将添加我的解决方案示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2021-01-28
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多