I have to convert the following code using Repo.insert/2
def create_question(attrs) do
%Question{}
|> Question.creation_changeset(attrs)
|> Repo.insert()
end
to use a transaction:
def create_question(attrs) do
question_changeset =
Question.creation_changeset(%Question{}, attrs)
Multi.new()
|> Multi.insert(:question, question_changeset)
|> Multi.run(:do_something, fn _repo, %{question: question} ->
# do something
{:ok, nil}
end)
|> Repo.transaction()
end
The problem is that now I have to change the code of my controller because the return value of Repo.transaction/2
is different than the return value of Repo.insert/2
.
The controller’s action code is the following:
def create(conn, %{"question" => question_params}) do
case Quiz.create_question(question_params) do
{:ok, question} ->
conn
|> put_flash(:info, "Question created successfully.")
|> redirect(to: Routes.admin_question_path(conn, :show, question))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
I think it’s wrong to change controller’s code whether I use a transaction or not? I think that the controller always either needs a struct or a changeset to display the errors, just as Repo.insert/2
returns?
Any advice is welcome on how to refactor that properly, on where I have to change code.