How to use dataloader when parent isn't a struct?

Hello!

How do you go about using dataloader when the parent field returns a map instead of struct. In my case the parent field (block) doesn’t map cleanly to one single table so I have to grab fields from a number of tables and create a map with the fields I need to return. Unfortunately this completely breaks dataloader which relies on the associations in a struct.

  object :block do
    field :author, :user, resolve: dataloader(Scribe.Accounts, :user)
  end

My current fix is to create a custom resolver for the author, i.e. don’t use dataloader (this is obviously not ideal)

  object :block do
    field :author, :user do
      resolve(&ScribeWeb.Resolvers.Accounts.get_user/3)
    end
  end

Does anyone know how to still use dataloader in this situation? Only things I can think of are to using a custom run_batch implementation (don’t understand this nearly well enough to attempt it) or use an embedded schema for the block (this is a wild guess, I’ve never used an embedded schema before).

Thanks in advance for the help!

Not at all! It just changes how you use it. It might be a little bit easier to show you a concrete example though if you show us how your get_user/3 function works.

Interesting! So my implementation is pretty simple, it just looks for the user_id field in the parent and then calls a context function which does a lookup by that ID. If the ID happens to match the current users ID I grab the current user struct out of the Absinthe context (It’s placed there using a Plug) to save the unnecessary query.

  def get_user(%{user_id: id}, _args, %{context: %{current_user: user}}) do
    if user.id == id do
      {:ok, user}
    else
      {:ok, Accounts.get_user(id)}
    end
  end

Excited to hear your suggestion :slight_smile: