I have an application that allows users to create and play quizzes. Each question in the quiz has four answers, stored in separate tables. Each question also has a correct_answer field which references a particular answer. In my channel, I create a question from the passed parameters, and then use Enum.map
to create four answers, using another map
to get the ids, and then updating the question with the first of these ids as the correct answer. The code is as follows:
def handle_in("questions:create", %{"question" => %{"body" => body}}, socket) do
question_params = %{quiz_id: socket.assigns.quiz_id, body: body}
question =
%Question{}
|> Question.changeset(question_params)
|> Repo.insert!
answer =
Enum.map(1..4, fn x ->
%Answer{}
|> Answer.changeset(%{body: "Answer #{x}", question_id: question.id})
|> Repo.insert!
end)
|> Enum.map(&(&1.id))
|> List.first
changeset = Question.changeset(question, %{correct_answer: answer})
case Repo.update(changeset) do
{:ok, question} ->
question = Repo.preload(question, :answers)
view = QuestionView.render("show.json", %{question: question})
{:reply, {:ok, view}, socket}
{:error, _changeset} ->
{:reply, {:error, %{error: "Error creating question"}}, socket}
end
end
This works, but it doesn’t seem very efficient - there’s a lot of going back and forth and updating. Is there a better way of doing it?