From 35f26d87df380225824a723805851ff5cd654117 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Tue, 4 Dec 2018 13:20:43 -0500 Subject: [PATCH] Refactor queries and channel --- lib/chess/repo/queries.ex | 34 ++++++++++++++++---- lib/chess/store/game.ex | 8 ++--- lib/chess/store/move.ex | 12 ++++++- lib/chess/store/user.ex | 9 ++---- lib/chess_web/channels/game_channel.ex | 28 +++------------- lib/chess_web/controllers/game_controller.ex | 26 ++++----------- lib/chess_web/views/game_channel_view.ex | 33 +++++++++++++++++++ test/chess/move_list_test.exs | 3 -- test/chess/store/move_test.exs | 1 - 9 files changed, 89 insertions(+), 65 deletions(-) create mode 100644 lib/chess_web/views/game_channel_view.ex diff --git a/lib/chess/repo/queries.ex b/lib/chess/repo/queries.ex index cfa469b..832db05 100644 --- a/lib/chess/repo/queries.ex +++ b/lib/chess/repo/queries.ex @@ -6,24 +6,46 @@ defmodule Chess.Repo.Queries do alias Chess.Repo alias Chess.Store.Game alias Chess.Store.User + alias Chess.Store.Move + + def games_for_index(user) do + Game + |> Game.for_user(user) + |> preload([:user, :opponent]) + |> Repo.all + end + + def game_for_show(user, game_id) do + Game + |> Game.for_user(user) + |> preload([:user, :opponent]) + |> Repo.get!(game_id) + end def game_for_info(user_id, game_id) do - user_id - |> Game.for_user_id() + Game + |> Game.for_user_id(user_id) |> preload([:moves, :user, :opponent]) |> Repo.get!(game_id) end def game_with_moves(user_id, game_id) do - user_id - |> Game.for_user_id() + Game + |> Game.for_user_id(user_id) |> preload(:moves) |> Repo.get!(game_id) end + def moves_with_captures(game_id) do + Move + |> Move.for_game_id(game_id) + |> Move.with_captures + |> Repo.all + end + def opponents(user, query_string) do - user - |> User.opponents + User + |> User.opponents(user) |> User.matches(query_string) end end diff --git a/lib/chess/store/game.ex b/lib/chess/store/game.ex index d7a67f4..5831adf 100644 --- a/lib/chess/store/game.ex +++ b/lib/chess/store/game.ex @@ -51,12 +51,12 @@ defmodule Chess.Store.Game do def _change_turn("black"), do: "white" def _change_turn("white"), do: "black" - def for_user(user) do - for_user_id(user.id) + def for_user(query, user) do + for_user_id(query, user.id) end - def for_user_id(user_id) do - from game in Game, + def for_user_id(query, user_id) do + from game in query, where: game.user_id == ^user_id, or_where: game.opponent_id == ^user_id end diff --git a/lib/chess/store/move.ex b/lib/chess/store/move.ex index 13993d5..4ab2a61 100644 --- a/lib/chess/store/move.ex +++ b/lib/chess/store/move.ex @@ -5,6 +5,7 @@ defmodule Chess.Store.Move do use Timex.Ecto.Timestamps import Ecto.Changeset + import Ecto.Query alias Chess.Store.Game @@ -26,11 +27,20 @@ defmodule Chess.Store.Move do |> validate_required(required_attrs()) end + def for_game_id(query, game_id) do + from move in query, + where: move.game_id == ^game_id + end + + def with_captures(query) do + from move in query, + where: not is_nil(move.piece_captured) + end + def transform(move) do %{ id: move.id, piece: move.piece, - piece_captured: move.piece_captured, from: <<97 + move.from["file"], 49 + move.from["rank"]>>, to: <<97 + move.to["file"], 49 + move.to["rank"]>>, } diff --git a/lib/chess/store/user.ex b/lib/chess/store/user.ex index e882741..e33577a 100644 --- a/lib/chess/store/user.ex +++ b/lib/chess/store/user.ex @@ -52,13 +52,8 @@ defmodule Chess.Store.User do |> unique_constraint(:email) end - def find_by_name(name) do - from user in __MODULE__, - where: user.name == ^name - end - - def opponents(user) do - from user in __MODULE__, + def opponents(query, user) do + from user in query, where: user.id != ^user.id end diff --git a/lib/chess_web/channels/game_channel.ex b/lib/chess_web/channels/game_channel.ex index 1c5f431..a60bc81 100644 --- a/lib/chess_web/channels/game_channel.ex +++ b/lib/chess_web/channels/game_channel.ex @@ -3,12 +3,12 @@ defmodule ChessWeb.GameChannel do use ChessWeb, :channel - import ChessWeb.GameView, only: [player: 2, opponent: 2] + import ChessWeb.GameView, only: [opponent: 2] + import ChessWeb.GameChannelView, + only: [after_join_payload: 2, update_payload: 1] - alias Chess.Board alias Chess.Emails alias Chess.Mailer - alias Chess.MoveList alias Chess.Moves alias Chess.Repo.Queries alias ChessWeb.Presence @@ -24,19 +24,8 @@ defmodule ChessWeb.GameChannel do socket.assigns.user_id |> Queries.game_for_info(game_id) - payload = %{ - player_id: socket.assigns.user_id, - opponent_id: opponent(game, socket.assigns.user_id).id, - player: player(game, socket.assigns.user_id), - opponent: opponent(game, socket.assigns.user_id).name, - board: Board.transform(game.board), - turn: game.turn, - state: game.state, - moves: MoveList.transform(game.moves), - } - socket - |> push("game:update", payload) + |> push("game:update", after_join_payload(socket, game)) track_presence(socket) @@ -126,13 +115,6 @@ defmodule ChessWeb.GameChannel do socket.assigns.user_id |> Queries.game_with_moves(socket.assigns.game_id) - payload = %{ - board: Board.transform(game.board), - turn: game.turn, - state: game.state, - moves: MoveList.transform(game.moves), - } - - ChessWeb.Endpoint.broadcast("game:#{game.id}", "game:update", payload) + ChessWeb.Endpoint.broadcast("game:#{game.id}", "game:update", update_payload(game)) end end diff --git a/lib/chess_web/controllers/game_controller.ex b/lib/chess_web/controllers/game_controller.ex index babca14..a7fa362 100644 --- a/lib/chess_web/controllers/game_controller.ex +++ b/lib/chess_web/controllers/game_controller.ex @@ -4,7 +4,7 @@ defmodule ChessWeb.GameController do alias Chess.Emails alias Chess.Mailer alias Chess.Store.Game - alias Chess.Store.User + alias Chess.Repo.Queries import Chess.Auth, only: [current_user: 1] @@ -14,10 +14,7 @@ defmodule ChessWeb.GameController do games = conn |> current_user() - |> Game.for_user() - |> Game.ordered - |> preload([:user, :opponent]) - |> Repo.all + |> Queries.games_for_index conn |> render("index.html", games: games, changeset: changeset) @@ -49,27 +46,16 @@ defmodule ChessWeb.GameController do |> redirect(to: game_path(conn, :show, game)) {:error, changeset} -> - opponents = - conn - |> current_user() - |> User.opponents() - |> Repo.all - conn - |> render("new.html", changeset: changeset, opponents: opponents) + |> render("new.html", changeset: changeset) end end def show(conn, %{"id" => id}) do - query = - conn - |> current_user() - |> Game.for_user() - |> preload([:user, :opponent]) - game = - query - |> Repo.get!(id) + conn + |> current_user + |> Queries.game_for_show(id) conn |> render("show.html", game: game) diff --git a/lib/chess_web/views/game_channel_view.ex b/lib/chess_web/views/game_channel_view.ex new file mode 100644 index 0000000..2933def --- /dev/null +++ b/lib/chess_web/views/game_channel_view.ex @@ -0,0 +1,33 @@ +defmodule ChessWeb.GameChannelView do + @moduledoc false + + use ChessWeb, :view + + import ChessWeb.GameView, only: [player: 2, opponent: 2] + + alias Chess.Board + + alias Chess.MoveList + + def after_join_payload(socket, game) do + %{ + player_id: socket.assigns.user_id, + opponent_id: opponent(game, socket.assigns.user_id).id, + player: player(game, socket.assigns.user_id), + opponent: opponent(game, socket.assigns.user_id).name, + board: Board.transform(game.board), + turn: game.turn, + state: game.state, + moves: MoveList.transform(game.moves), + } + end + + def update_payload(game) do + %{ + board: Board.transform(game.board), + turn: game.turn, + state: game.state, + moves: MoveList.transform(game.moves), + } + end +end diff --git a/test/chess/move_list_test.exs b/test/chess/move_list_test.exs index 9b7e2a8..9f19584 100644 --- a/test/chess/move_list_test.exs +++ b/test/chess/move_list_test.exs @@ -31,14 +31,12 @@ defmodule Chess.MoveListTest do %{ id: nil, piece: %{"type" => "pawn", "colour" => "white"}, - piece_captured: nil, from: "e2", to: "e4" }, %{ id: nil, piece: %{"type" => "pawn", "colour" => "black"}, - piece_captured: nil, from: "e7", to: "e5" } @@ -47,7 +45,6 @@ defmodule Chess.MoveListTest do %{ id: nil, piece: %{"type" => "knight", "colour" => "white"}, - piece_captured: nil, from: "b1", to: "c3" } diff --git a/test/chess/store/move_test.exs b/test/chess/store/move_test.exs index a5f4844..0875460 100644 --- a/test/chess/store/move_test.exs +++ b/test/chess/store/move_test.exs @@ -89,7 +89,6 @@ defmodule Chess.Store.MoveTest do assert Move.transform(move) == %{ id: nil, piece: %{"type" => "pawn", "colour" => "white"}, - piece_captured: %{"type" => "pawn", "colour" => "black"}, from: "e2", to: "e4" }