Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Associations #3

Merged
merged 2 commits into from
Jul 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/scoreboard/games/games.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ defmodule Scoreboard.Games do

alias Scoreboard.Games.Player

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

def query(queryable, _params) do
queryable
end

def get(queryable, id) do
case Repo.get(queryable, id) do
nil ->
Expand Down
26 changes: 21 additions & 5 deletions lib/scoreboard_web/schema.ex
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
defmodule ScoreboardWeb.Schema do
use Absinthe.Schema
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
alias Scoreboard.Games

def context(ctx) do
loader =
Dataloader.new |> Dataloader.add_source(:games, Games.data())

Map.put(ctx, :loader, loader)
end

def plugins do
[Absinthe.Middleware.Dataloader] ++ Absinthe.Plugin.defaults()
end

@desc "A Game"
object :game do
field(:id, non_null(:id))
field(:name, non_null(:string))
field(:scores, list_of(:score), resolve: dataloader(:games))
end

@desc "A Player"
object :player do
field(:id, non_null(:id))
field(:name, non_null(:string))
field(:scores, list_of(:score), resolve: dataloader(:games))
end

# @desc "A Score."
# object :score do
# field(:id, non_null(:id))
# field(:total, non_null(:integer))
# end
@desc "A Score."
object :score do
field(:id, non_null(:id))
field(:total, non_null(:integer))
field(:player, :player, resolve: dataloader(:games))
field(:game, :game, resolve: dataloader(:games))
end

query do
field :game, :game do
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ defmodule Scoreboard.Mixfile do
{:postgrex, ">= 0.0.0"},
{:gettext, "~> 0.11"},
{:absinthe, "~> 1.4"},
{:cowboy, "~> 1.0"}
{:cowboy, "~> 1.0"},
{:dataloader, "~> 1.0.0"}
]
end

Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
"dataloader": {:hex, :dataloader, "1.0.2", "90e788dc507bb80f7281f2d3d6c6e4bb1d18709c8351392365b6a0950bfe9f7d", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
Expand Down
37 changes: 34 additions & 3 deletions test/scoreboard_web/schema_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Scoreboard.SchemaTest do
use Scoreboard.DataCase

alias Scoreboard.Games.{Game, Player}
alias Scoreboard.Games.{Game, Player, Score}
alias Scoreboard.Repo

setup do
Expand All @@ -11,8 +11,8 @@ defmodule Scoreboard.SchemaTest do
%{game: game, player: player}
end

describe "scores" do
test "We can get our fake data", context do
describe("top level queries") do
test("We can get our fake data", context) do
document = """
{
game(id: "#{context.game.id}") {
Expand All @@ -33,4 +33,35 @@ defmodule Scoreboard.SchemaTest do
assert get_in(data, ["player", "name"]) == context.player.name
end
end

describe("nested queries") do
test("We can query associations", context) do
score = Repo.insert!(%Score{game_id: context.game.id, player_id: context.player.id, total: 101})

document = """
{
game(id: "#{context.game.id}") {
id
name
scores {
total
player {
id
name
}
}
}
}
"""

result = Absinthe.run(document, ScoreboardWeb.Schema)

assert {:ok, %{data: data}} = result
assert get_in(data, ["game", "name"]) == context.game.name

first = fn :get, data, next -> data |> hd() |> next.() end
assert get_in(data, ["game", "scores", first, "total"]) == score.total
assert get_in(data, ["game", "scores", first, "player", "name"]) == context.player.name
end
end
end