Skip to content

Instantly share code, notes, and snippets.

@MartinElvar
Last active November 25, 2016 13:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinElvar/e2f8bbbbdc2dc5a74abfdb8ba2792e6c to your computer and use it in GitHub Desktop.
Save MartinElvar/e2f8bbbbdc2dc5a74abfdb8ba2792e6c to your computer and use it in GitHub Desktop.
defmodule GraphqlHelpers do
import Ecto.Query
defmacro has_many(model, foreign_key) do
quote do
resolve fn subject, _, _ ->
batch({GraphqlHelpers, :process_has_many, {unquote(model), unquote(foreign_key)}}, subject.id, fn (batch_result) ->
{:ok, Map.get(batch_result, subject.id, %{})}
end)
end
end
end
defmacro belongs_to(model) do
quote do
resolve fn subject, _, _ ->
[_ | module] = Module.split(unquote(model))
key = Macro.underscore(module |> List.last) <> "_id" |> String.to_atom
id = Map.get(subject, key)
batch({GraphqlHelpers, :process_belongs_to, unquote(model)}, id, fn batch_result ->
{:ok, Map.get(batch_result, id, %{})}
end)
end
end
end
def process_has_many({model, foreign_key}, ids) do
model
|> where([m], field(m, ^foreign_key) in ^ids)
|> ApiEndpoint.Repo.all
|> Enum.group_by(fn record -> Map.get(record, foreign_key) end)
end
def process_belongs_to(model, ids) do
model
|> where([m], m.id in ^ids)
|> ApiEndpoint.Repo.all
|> Map.new(&{&1.id, &1})
end
end
defmodule Storages.Types do
use Absinthe.Schema.Notation
import GraphqlHelpers
object :storage do
field :id, :id
field :title, :string
field :description, :string
field :slug, :string
field :status, :string
field :latitude, :float
field :longitude, :float
field :user, :user, do: belongs_to(Users.User)
end
end
defmodule Users.Types do
use Absinthe.Schema.Notation
import GraphqlHelpers
object :user do
field :id, :id
field :first_name, :string
field :last_name, :string
field :email, :string
field :phone, :string
field :storages, list_of(:storage), do: has_many(Storages.Storage, :user_id)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment