grangerelixx

grangerelixx

How to use same dataloader batch key for two fields?

Hi,

I am currently trying to resolve two fields:

object :post do
    field(:id, non_null(:uuid))

    field :title, non_null(:string) do
      resolve(&Resolvers.Blog.title_for_post/3)
    end

    field :category, non_null(:string) do
      resolve(&Resolvers.Blog.category_for_post/3)
    end
end

I have the following functions in my resolver:

def title_for_post(
        post,
        _,
        params
      ) do
    tenant = params.tenant
    batch_key = {:one, Author, %{tenant: tenant}}

    value = [post_titles: post]
    Batcher.batching_fields(loader, Authors, batch_key, value)
  end

  def category_for_post(
        post,
        _,
        params
      ) do
    tenant = params.tenant
    batch_key = {:one, Author, %{tenant: tenant}}

    value = [post_categories: post]
    Batcher.batching_fields(loader, Authors, batch_key, value)
  end

Batcher.ex has the following function

def batching_fields(loader, module, batch_key, value) do
    Dataloader.load(loader, module, batch_key, value)
    |> on_load(fn loader ->
      {:ok, loader |> Dataloader.get(module, batch_key, value)}
    end)
  end

And the Post dataloader currently has the following code

def data() do
    Dataloader.Ecto.new(MyApp.Repo, query: &query/2, run_batch: &run_batch/5)
  end

  def query(Author, %{tenant: tenant}) do
    Authors.get_authors(tenant)
  end

  def run_batch(
        Author,
        authors_query,
        :post_titles,
        posts,
        _
      ) do
    author_ids =
      Enum.map(posts, & &1.author_id)

    authors_map_from_query(authors_query, author_ids)
    |> title_list(author_ids)
  end

  def run_batch(
        Author,
        authors_query,
        :post_categories,
        posts,
        _
      ) do
    author_ids =
      Enum.map(posts, & &1.author_id)

    authors_map_from_query(authors_query, author_ids)
    |> category_list(author_ids)
  end

This works but I see separate queries for title and category fields when I try to query for

query
    {
     posts
         {
          id
          title
          category
         }
     }

I would like to get a much efficient approach which is preferably using the same batch key when resolving for both fields. Any suggestions on how to achieve this?

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement