Current section

Files

Jump to
ami lib ami answer.ex
Raw

lib/ami/answer.ex

defmodule Ami.Answer do
use Ecto.Schema
import Ecto.{
Query,
Changeset
}
alias Ami.{
UserAnswer,
Question
}
schema "answers" do
field(:correct_answer, :boolean)
field(:explanation, :string)
field(:position, :integer)
field(:value, :string)
belongs_to(:question, Question)
has_many(:user_answers, UserAnswer)
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [
:question_id,
:correct_answer,
:explanation,
:position,
:value
])
|> validate_required([:value])
# |> check_correct_answer_count(params)
|> check_explanation_presence(params)
|> case do
%{valid?: false, changes: changes} = changeset when changes == %{correct_answer: false} ->
%{changeset | action: :ignore}
%{valid?: false, changes: changes} = changeset when changes == %{} ->
%{changeset | action: :ignore}
changeset ->
changeset
end
# |> maybe_mark_for_deletion
end
def editing_changeset(struct, params \\ %{}) do
struct
|> cast(params, [
:question_id,
:correct_answer,
:explanation,
:position,
:value
])
end
@doc """
Check if a correct answer has got an associated explanation. Ensure Moderator/Admin doesn't forget to add the correct answer explanation
"""
defp check_explanation_presence(changeset, params) do
cond do
params["correct_answer"] == "true" && params["explanation"] == "" ->
add_error(
changeset,
:explanation,
"A correct answer must have an explanation."
)
true ->
changeset
end
end
@doc """
Check proper correct answers count by question type :
- single correct answer's question must have 1 correct answer
- multiple correct answers question must have at least 2 correct answers
"""
defp check_correct_answer_count(changeset, %{"question_id" => _} = params) do
question =
Repo.get!(Question, params["question_id"])
|> Repo.preload([:answers])
cond do
question.answer_type == 0 && Enum.any?(question.answers, fn answer -> answer.correct_answer == true end) && params["correct_answer"] == "true" ->
add_error(
changeset,
:correct_answer_single,
"You can have only 1 correct answer."
)
question.answer_type == 0 && length(question.answers) >= 3 &&
!Enum.any?(question.answers, fn answer -> answer.correct_answer == true end) &&
params["correct_answer"] != "true" ->
add_error(
changeset,
:correct_answer,
"Don't forget to enter a correct answer."
)
question.answer_type == 1 && length(question.answers) >= 4 &&
length(Enum.filter(question.answers, fn answer -> answer.correct_answer end)) in [0, 1] &&
params["correct_answer"] != "true" ->
add_error(
changeset,
:correct_answer_multiple,
"Don't forget to specifiy several correct answers."
)
true ->
changeset
end
end
defp check_correct_answer_count(changeset, %{} = params) do
if !is_nil(changeset.data.question_id) do
question =
Repo.get!(Question, changeset.data.question_id)
|> Repo.preload([:answers])
test_changeset_correct_answers(changeset, question)
else
changeset
end
end
defp test_changeset_correct_answers(changeset, question) do
cond do
question.answer_type == 0 &&
Enum.any?(question.answers, fn answer -> answer.correct_answer end) && changeset.changes[:correct_answer] == "true" ->
add_error(
changeset,
:correct_answer_single,
"You can have only 1 correct answer."
)
question.answer_type == 0 && length(question.answers) >= 3 &&
!Enum.any?(question.answers, fn answer -> answer.correct_answer end) &&
changeset.changes[:correct_answer] != "true" ->
add_error(
changeset,
:correct_answer,
"Don't forget to enter a correct answer."
)
question.answer_type == 1 && length(question.answers) >= 4 &&
length(Enum.filter(question.answers, fn answer -> answer.correct_answer end)) in [0, 1] &&
changeset.changes[:correct_answer] != "true" ->
add_error(
changeset,
:correct_answer_multiple,
"Don't forget to specifiy several correct answers."
)
true ->
changeset
end
end
end