Как я могу использовать Absinthe Dataloader для многих отношений - PullRequest
1 голос
/ 13 октября 2019

В моем приложении 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. У меня есть импортированные помощники. Могу ли я что-то пропустить?

1 Ответ

0 голосов
/ 15 октября 2019

Я думаю, что вы должны предварительно загрузить отношения с художниками вручную из Ecto, прежде чем передать их Абсенту.

Например, выборка вызывает как:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...