Skip to content

Commit

Permalink
enhancement(elixir): Preload all questions
Browse files Browse the repository at this point in the history
  • Loading branch information
jtkpiotr authored Oct 16, 2017
1 parent 1947515 commit 69e4cd4
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 22 deletions.
35 changes: 35 additions & 0 deletions aion/lib/aion/room_channel/question_set.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule Aion.RoomChannel.QuestionSet do
@moduledoc """
This module provides logic for generating new question set
"""
alias Aion.{Question, Answer}
require Logger

@type t :: %__MODULE__{questions: (list Question.t), current_question: Question.t, answers: (list Answer.t)}

defstruct questions: [],
current_question: nil,
answers: []

@spec create((list Question.t), integer) :: __MODULE__.t
def create(questions, room_id) do
case questions do
[] ->
%{questions: [], current_question: nil, answers: []}

[last_question] ->
remaining_questions = Question.get_questions_by_room_id(room_id)
build_new(last_question, remaining_questions)

[next_question | remaining_questions] ->
build_new(next_question, remaining_questions)
end
end

@spec build_new(Question.t, (list Question.t)) :: __MODULE__.t
defp build_new(current_question, remaining_questions) do
answers = Answer.get_answers(current_question.id)
Logger.debug fn -> "Answers: #{inspect(Enum.map(answers, fn answer -> answer.content end))}" end
%{questions: remaining_questions, current_question: current_question, answers: answers}
end
end
41 changes: 22 additions & 19 deletions aion/lib/aion/room_channel/room.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,31 @@ defmodule Aion.RoomChannel.Room do
This module represents one game room, and fetches resources from the db
"""
alias Aion.{Question, Answer}
alias Aion.RoomChannel.{Room, UserRecord}
alias Aion.RoomChannel.{Room, UserRecord, QuestionSet}
require Logger

@type t :: %__MODULE__{users: %{String.t => UserRecord.t},
users_count: integer,
question: Question.t,
answers: list Answer.t}
questions: (list Question.t),
current_question: Question.t,
answers: (list Answer.t)}

defstruct users: %{},
users_count: 0,
question: nil,
questions: [],
current_question: nil,
answers: []

@spec new(integer, [question: nil | Question.t]) :: %__MODULE__{}
@spec new(integer, [current_question: nil | Question.t]) :: %__MODULE__{}
def new(room_id, state \\ []) do
case state do
[] ->
%Room{}
|> load_questions(room_id)
|> change_question(room_id)

{:question, question} ->
%Room{question: question}
{:current_question, question} ->
%Room{current_question: question}

_ -> Logger.error fn -> "Unexpected state passed to Room.new: #{state}" end
%Room{}
Expand All @@ -50,8 +53,17 @@ defmodule Aion.RoomChannel.Room do
"""
@spec change_question(%__MODULE__{}, integer) :: __MODULE__.t
def change_question(room, room_id) do
room
|> struct(get_new_question_with_answers(room_id))
new_questions_with_answers = QuestionSet.create(room.questions, room_id)
struct(room, new_questions_with_answers)
end

@spec load_questions(%__MODULE__{}, integer) :: __MODULE__.t
def load_questions(room, room_id) do
questions =
room_id
|> Question.get_questions_by_room_id()
|> Enum.shuffle()
struct(room, %{questions: questions})
end

@spec add_user(__MODULE__.t, UserRecord.t) :: __MODULE__.t
Expand All @@ -73,15 +85,6 @@ defmodule Aion.RoomChannel.Room do

@spec get_current_question(__MODULE__.t) :: Question.t
def get_current_question(room) do
room.question
end

@spec get_new_question_with_answers(integer) :: %{question: Question.t, answers: list Answer.t}
defp get_new_question_with_answers(room_id) do
question = Question.get_random_question(room_id)
answers = Answer.get_answers(question.id)
Logger.debug fn -> "Answers: #{inspect(Enum.map(answers, fn answer -> answer.content end))}" end

%{question: question, answers: answers}
room.current_question
end
end
2 changes: 1 addition & 1 deletion aion/test/lib/room_channel/monitor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Aion.MonitorTest do
@question %Question{content: "Content"}

setup do
Monitor.create(@room_id, question: @question)
Monitor.create(@room_id, current_question: @question)
:ok
end

Expand Down
25 changes: 24 additions & 1 deletion aion/test/models/question_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Aion.QuestionTest do
use Aion.ModelCase

alias Aion.Question
alias Aion.{Question, RoomCategory, Room, Category}

@valid_attrs %{content: "some content", image_name: "some content"}
@invalid_attrs %{}
Expand All @@ -16,6 +16,29 @@ defmodule Aion.QuestionTest do
refute changeset.valid?
end

test "get_questions_by_room_id when there are no questions" do
room1 = Repo.insert! %Room{}

result = Question.get_questions_by_room_id(room1.id)
assert length(result) == 0
end

test "get_questions_by_room_id when there are some questions" do
room1 = Repo.insert! %Room{}
room2 = Repo.insert! %Room{}

question_1 = Repo.insert! %Question{category: (Repo.insert! %Category{})}
question_2 = Repo.insert! %Question{category: (Repo.insert! %Category{})}
question_3 = Repo.insert! %Question{category: (Repo.insert! %Category{})}

room_category1 = Repo.insert! %RoomCategory{room_id: room1.id, category_id: question_1.category_id}
room_category2 = Repo.insert! %RoomCategory{room_id: room1.id, category_id: question_2.category_id}
room_category2 = Repo.insert! %RoomCategory{room_id: room2.id, category_id: question_3.category_id}

result = Question.get_questions_by_room_id(room1.id)
assert length(result) == 2
end

def get_question(question_id) do
Repo.get(Question, question_id)
end
Expand Down
12 changes: 11 additions & 1 deletion aion/web/models/question.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Aion.Question do

use Aion.Web, :model
alias Aion.Repo
alias Aion.{Question, Category}
alias Aion.{Question, Category, RoomCategory, Room}

schema "questions" do
field :content, :string
Expand Down Expand Up @@ -36,6 +36,16 @@ defmodule Aion.Question do
Repo.get(Question, question_id)
end

@spec get_questions_by_room_id(integer) :: Question.t
def get_questions_by_room_id(room_id) do
Repo.all(
from q in Question,
join: rc in RoomCategory, on: rc.category_id == q.category_id,
join: r in Room, on: r.id == rc.room_id,
where: r.id == ^room_id
)
end

@spec get_random_question(integer) :: Question.t
def get_random_question(room_id) do
query = Repo.query("
Expand Down

0 comments on commit 69e4cd4

Please sign in to comment.