handle raise conditions in multiple uploads

This commit is contained in:
Berenice Medel 2021-11-18 15:36:51 -06:00
parent 984c1c8523
commit 64969fca31
4 changed files with 40 additions and 30 deletions

View file

@ -4,7 +4,6 @@ defmodule LiveBeats.Accounts.User do
alias LiveBeats.Accounts.{User, Identity} alias LiveBeats.Accounts.{User, Identity}
@max_songs 30
schema "users" do schema "users" do
field :email, :string field :email, :string
@ -62,12 +61,6 @@ defmodule LiveBeats.Accounts.User do
|> validate_username() |> validate_username()
end end
def songs_changeset(%User{} = user, params) do
user
|> cast(params, [:songs_number])
|> validate_required([:songs_number])
|> validate_number(:songs_number, less_than_or_equal_to: @max_songs)
end
defp validate_email(changeset) do defp validate_email(changeset) do
changeset changeset

View file

@ -11,6 +11,7 @@ defmodule LiveBeats.MediaLibrary do
@pubsub LiveBeats.PubSub @pubsub LiveBeats.PubSub
@auto_next_threshold_seconds 5 @auto_next_threshold_seconds 5
@max_songs 30
defdelegate stopped?(song), to: Song defdelegate stopped?(song), to: Song
defdelegate playing?(song), to: Song defdelegate playing?(song), to: Song
@ -157,15 +158,31 @@ defmodule LiveBeats.MediaLibrary do
Ecto.Multi.insert(acc, {:song, ref}, chset) Ecto.Multi.insert(acc, {:song, ref}, chset)
end) end)
|> Ecto.Multi.update(:update_songs_number, fn acc -> |> Ecto.Multi.run(:valid_songs_number, fn _repo, changes ->
new_songs = acc |> Enum.filter(&match?({{:song, _ref}, _}, &1)) |> Enum.count()
user = Accounts.get_user!(user.id) user = Accounts.get_user!(user.id)
new_songs_count = changes |> Enum.filter(&match?({{:song, _ref}, _}, &1)) |> Enum.count()
user_params = %{ if user.songs_number + new_songs_count <= @max_songs do
songs_number: user.songs_number + new_songs {:ok, new_songs_count}
} else
{:error, :songs_limit_exceeded}
Accounts.User.songs_changeset(user, user_params) end
end)
|> Ecto.Multi.update_all(
:update_songs_number,
fn %{valid_songs_number: new_songs_count} ->
from(u in Accounts.User,
where: u.id == ^user.id and u.songs_number == ^user.songs_number,
update: [inc: [songs_number: ^new_songs_count]]
)
end,
[]
)
|> Ecto.Multi.run(:is_songs_number_updated?, fn _repo, %{update_songs_number: result} ->
case result do
{1, _} -> {:ok, user}
_ -> {:error, :invalid}
end
end) end)
case LiveBeats.Repo.transaction(multi) do case LiveBeats.Repo.transaction(multi) do
@ -180,16 +197,14 @@ defmodule LiveBeats.MediaLibrary do
|> Enum.into(%{})} |> Enum.into(%{})}
{:error, failed_op, failed_val, _changes} -> {:error, failed_op, failed_val, _changes} ->
reason = failed_op =
case {failed_op, format_errors(failed_val)} do case failed_op do
{:update_songs_number, %{songs_number: _errors}} -> {:song, number} -> "Song ##{String.to_integer(number) + 1}"
{:songs_number, :songs_limit_exceeded} :is_songs_number_updated? -> :invalid
failed_op -> failed_op
_ ->
{:form, :invalid}
end end
{:error, reason} {:error, {failed_op, failed_val}}
end end
end end
@ -369,12 +384,4 @@ defmodule LiveBeats.MediaLibrary do
end end
defp topic(user_id) when is_integer(user_id), do: "profile:#{user_id}" defp topic(user_id) when is_integer(user_id), do: "profile:#{user_id}"
defp format_errors(changeset) do
Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)
end
end end

View file

@ -157,6 +157,10 @@ defmodule LiveBeatsWeb.SongLive.UploadFormComponent do
defp file_error(%{kind: :invalid} = assigns), do: ~H|Something went wrong| defp file_error(%{kind: :invalid} = assigns), do: ~H|Something went wrong|
defp file_error(%{kind: %Ecto.Changeset{} = changeset} = assigns) do
~H|<%= LiveBeatsWeb.ErrorHelpers.translate_changeset_errors(@kind) %>|
end
defp file_error(%{kind: {msg, opts}} = assigns) when is_binary(msg) and is_list(opts) do defp file_error(%{kind: {msg, opts}} = assigns) when is_binary(msg) and is_list(opts) do
~H|<%= LiveBeatsWeb.ErrorHelpers.translate_error(@kind) %>| ~H|<%= LiveBeatsWeb.ErrorHelpers.translate_error(@kind) %>|
end end

View file

@ -63,4 +63,10 @@ defmodule LiveBeatsWeb.ErrorHelpers do
Gettext.dgettext(LiveBeatsWeb.Gettext, "errors", msg, opts) Gettext.dgettext(LiveBeatsWeb.Gettext, "errors", msg, opts)
end end
end end
def translate_changeset_errors(changeset) do
changeset.errors
|> Enum.map(fn {key, value} -> "#{key} #{translate_error(value)}" end)
|> Enum.join("\n")
end
end end