forked from shibao/cannery
		
	harden tags context
This commit is contained in:
		| @@ -12,13 +12,12 @@ defmodule Cannery.Tags do | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> list_tags() | ||||
|       iex> list_tags(%User{id: 123}) | ||||
|       [%Tag{}, ...] | ||||
|  | ||||
|   """ | ||||
|   @spec list_tags(User.t() | User.id()) :: [Tag.t()] | ||||
|   def list_tags(%{id: user_id}), do: list_tags(user_id) | ||||
|   def list_tags(user_id), do: Repo.all(from t in Tag, where: t.user_id == ^user_id) | ||||
|   @spec list_tags(User.t()) :: [Tag.t()] | ||||
|   def list_tags(%{id: user_id}), do: Repo.all(from t in Tag, where: t.user_id == ^user_id) | ||||
|  | ||||
|   @doc """ | ||||
|   Gets a single tag. | ||||
| @@ -27,72 +26,77 @@ defmodule Cannery.Tags do | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> get_tag!(123) | ||||
|       iex> get_tag!(123, %User{id: 123}) | ||||
|       %Tag{} | ||||
|  | ||||
|       iex> get_tag!(456) | ||||
|       iex> get_tag!(456, %User{id: 123}) | ||||
|       ** (Ecto.NoResultsError) | ||||
|  | ||||
|   """ | ||||
|   @spec get_tag!(Tag.id()) :: Tag.t() | ||||
|   def get_tag!(id), do: Repo.get!(Tag, id) | ||||
|   @spec get_tag!(Tag.id(), User.t()) :: Tag.t() | ||||
|   def get_tag!(id, %User{id: user_id}), | ||||
|     do: Repo.one!(from t in Tag, where: t.id == ^id and t.user_id == ^user_id) | ||||
|  | ||||
|   @doc """ | ||||
|   Creates a tag. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> create_tag(%{field: value}) | ||||
|       iex> create_tag(%{field: value}, %User{id: 123}) | ||||
|       {:ok, %Tag{}} | ||||
|  | ||||
|       iex> create_tag(%{field: bad_value}) | ||||
|       iex> create_tag(%{field: bad_value}, %User{id: 123}) | ||||
|       {:error, %Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec create_tag(attrs :: map()) :: {:ok, Tag.t()} | {:error, Changeset.t(Tag.new_tag())} | ||||
|   def create_tag(attrs), do: %Tag{} |> Tag.changeset(attrs) |> Repo.insert() | ||||
|   @spec create_tag(attrs :: map(), User.t()) :: | ||||
|           {:ok, Tag.t()} | {:error, Changeset.t(Tag.new_tag())} | ||||
|   def create_tag(attrs, %User{id: user_id}), | ||||
|     do: %Tag{} |> Tag.create_changeset(attrs |> Map.put("user_id", user_id)) |> Repo.insert() | ||||
|  | ||||
|   @doc """ | ||||
|   Updates a tag. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> update_tag(tag, %{field: new_value}) | ||||
|       iex> update_tag(tag, %{field: new_value}, %User{id: 123}) | ||||
|       {:ok, %Tag{}} | ||||
|  | ||||
|       iex> update_tag(tag, %{field: bad_value}) | ||||
|       iex> update_tag(tag, %{field: bad_value}, %User{id: 123}) | ||||
|       {:error, %Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec update_tag(Tag.t(), attrs :: map()) :: {:ok, Tag.t()} | {:error, Changeset.t(Tag.t())} | ||||
|   def update_tag(tag, attrs), do: tag |> Tag.changeset(attrs) |> Repo.update() | ||||
|   @spec update_tag(Tag.t(), attrs :: map(), User.t()) :: | ||||
|           {:ok, Tag.t()} | {:error, Changeset.t(Tag.t())} | ||||
|   def update_tag(%Tag{user_id: user_id} = tag, attrs, %User{id: user_id}), | ||||
|     do: tag |> Tag.update_changeset(attrs) |> Repo.update() | ||||
|  | ||||
|   @doc """ | ||||
|   Deletes a tag. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> delete_tag(tag) | ||||
|       iex> delete_tag(tag, %User{id: 123}) | ||||
|       {:ok, %Tag{}} | ||||
|  | ||||
|       iex> delete_tag(tag) | ||||
|       iex> delete_tag(tag, %User{id: 123}) | ||||
|       {:error, %Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec delete_tag(Tag.t()) :: {:ok, Tag.t()} | {:error, Changeset.t(Tag.t())} | ||||
|   def delete_tag(tag), do: tag |> Repo.delete() | ||||
|   @spec delete_tag(Tag.t(), User.t()) :: {:ok, Tag.t()} | {:error, Changeset.t(Tag.t())} | ||||
|   def delete_tag(%Tag{user_id: user_id} = tag, %User{id: user_id}), do: tag |> Repo.delete() | ||||
|  | ||||
|   @doc """ | ||||
|   Deletes a tag. | ||||
|  | ||||
|   ## Examples | ||||
|  | ||||
|       iex> delete_tag!(tag) | ||||
|       iex> delete_tag!(tag, %User{id: 123}) | ||||
|       %Tag{} | ||||
|  | ||||
|   """ | ||||
|   @spec delete_tag!(Tag.t()) :: Tag.t() | ||||
|   def delete_tag!(tag), do: tag |> Repo.delete!() | ||||
|   @spec delete_tag!(Tag.t(), User.t()) :: Tag.t() | ||||
|   def delete_tag!(%Tag{user_id: user_id} = tag, %User{id: user_id}), do: tag |> Repo.delete!() | ||||
|  | ||||
|   @doc """ | ||||
|   Returns an `%Changeset{}` for tracking tag changes. | ||||
| @@ -106,7 +110,7 @@ defmodule Cannery.Tags do | ||||
|   @spec change_tag(Tag.t() | Tag.new_tag()) :: Changeset.t(Tag.t() | Tag.new_tag()) | ||||
|   @spec change_tag(Tag.t() | Tag.new_tag(), attrs :: map()) :: | ||||
|           Changeset.t(Tag.t() | Tag.new_tag()) | ||||
|   def change_tag(tag, attrs \\ %{}), do: Tag.changeset(tag, attrs) | ||||
|   def change_tag(tag, attrs \\ %{}), do: Tag.update_changeset(tag, attrs) | ||||
|  | ||||
|   @doc """ | ||||
|   Get a random tag bg_color in `#ffffff` hex format | ||||
|   | ||||
| @@ -26,7 +26,7 @@ defmodule Cannery.Tags.Tag do | ||||
|           name: String.t(), | ||||
|           bg_color: String.t(), | ||||
|           text_color: String.t(), | ||||
|           user: User.t(), | ||||
|           user: User.t() | nil, | ||||
|           user_id: User.id(), | ||||
|           inserted_at: NaiveDateTime.t(), | ||||
|           updated_at: NaiveDateTime.t() | ||||
| @@ -35,10 +35,18 @@ defmodule Cannery.Tags.Tag do | ||||
|   @type id() :: UUID.t() | ||||
|  | ||||
|   @doc false | ||||
|   @spec changeset(t() | new_tag(), attrs :: map()) :: Changeset.t(t() | new_tag()) | ||||
|   def changeset(tag, attrs) do | ||||
|   @spec create_changeset(t() | new_tag(), attrs :: map()) :: Changeset.t(t() | new_tag()) | ||||
|   def create_changeset(tag, attrs) do | ||||
|     tag | ||||
|     |> cast(attrs, [:name, :bg_color, :text_color, :user_id]) | ||||
|     |> validate_required([:name, :bg_color, :text_color, :user_id]) | ||||
|   end | ||||
|  | ||||
|   @doc false | ||||
|   @spec update_changeset(t() | new_tag(), attrs :: map()) :: Changeset.t(t() | new_tag()) | ||||
|   def update_changeset(tag, attrs) do | ||||
|     tag | ||||
|     |> cast(attrs, [:name, :bg_color, :text_color]) | ||||
|     |> validate_required([:name, :bg_color, :text_color, :user_id]) | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -29,9 +29,7 @@ defmodule CanneryWeb.LiveHelpers do | ||||
|  | ||||
|   def assign_defaults(socket, %{"user_token" => user_token} = _session) do | ||||
|     socket | ||||
|     |> assign_new(:current_user, fn -> | ||||
|       Accounts.get_user_by_session_token(user_token) | ||||
|     end) | ||||
|     |> assign_new(:current_user, fn -> Accounts.get_user_by_session_token(user_token) end) | ||||
|   end | ||||
|  | ||||
|   def assign_defaults(socket, _session) do | ||||
|   | ||||
| @@ -4,29 +4,21 @@ defmodule CanneryWeb.TagLive.FormComponent do | ||||
|   """ | ||||
|  | ||||
|   use CanneryWeb, :live_component | ||||
|  | ||||
|   alias Cannery.Tags | ||||
|   alias Ecto.Changeset | ||||
|  | ||||
|   @impl true | ||||
|   def update(%{tag: tag} = assigns, socket) do | ||||
|     changeset = Tags.change_tag(tag) | ||||
|  | ||||
|     {:ok, | ||||
|      socket | ||||
|      |> assign(assigns) | ||||
|      |> assign(:changeset, changeset)} | ||||
|     {:ok, socket |> assign(assigns) |> assign(:changeset, Tags.change_tag(tag))} | ||||
|   end | ||||
|  | ||||
|   @impl true | ||||
|   def handle_event("validate", %{"tag" => tag_params}, socket) do | ||||
|     tag_params = tag_params |> Map.put("user_id", socket.assigns.current_user.id) | ||||
|     changeset = socket.assigns.tag |> Tags.change_tag(tag_params) | ||||
|     {:noreply, socket |> assign(:changeset, changeset)} | ||||
|   def handle_event("validate", %{"tag" => tag_params}, %{assigns: %{tag: tag}} = socket) do | ||||
|     {:noreply, socket |> assign(:changeset, tag |> Tags.change_tag(tag_params))} | ||||
|   end | ||||
|  | ||||
|   def handle_event("save", %{"tag" => tag_params}, socket) do | ||||
|     save_tag(socket, socket.assigns.action, tag_params) | ||||
|   def handle_event("save", %{"tag" => tag_params}, %{assigns: %{action: action}} = socket) do | ||||
|     save_tag(socket, action, tag_params) | ||||
|   end | ||||
|  | ||||
|   @impl true | ||||
| @@ -76,32 +68,39 @@ defmodule CanneryWeb.TagLive.FormComponent do | ||||
|     """ | ||||
|   end | ||||
|  | ||||
|   defp save_tag(socket, :edit, tag_params) do | ||||
|     case Tags.update_tag(socket.assigns.tag, tag_params) do | ||||
|       {:ok, _tag} -> | ||||
|         {:noreply, | ||||
|          socket | ||||
|          |> put_flash(:info, dgettext("prompts", "Tag updated successfully")) | ||||
|          |> push_redirect(to: socket.assigns.return_to)} | ||||
|  | ||||
|       {:error, %Changeset{} = changeset} -> | ||||
|         {:noreply, socket |> assign(:changeset, changeset)} | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   defp save_tag(socket, :new, tag_params) do | ||||
|   defp save_tag( | ||||
|          %{assigns: %{tag: tag, current_user: current_user, return_to: return_to}} = socket, | ||||
|          :edit, | ||||
|          tag_params | ||||
|     |> Map.put("user_id", socket.assigns.current_user.id) | ||||
|     |> Tags.create_tag() | ||||
|     |> case do | ||||
|       {:ok, _tag} -> | ||||
|         {:noreply, | ||||
|          socket | ||||
|          |> put_flash(:info, dgettext("prompts", "Tag created successfully")) | ||||
|          |> push_redirect(to: socket.assigns.return_to)} | ||||
|        ) do | ||||
|     socket = | ||||
|       case Tags.update_tag(tag, tag_params, current_user) do | ||||
|         {:ok, %{name: tag_name}} -> | ||||
|           prompt = dgettext("prompts", "%{name} updated successfully", name: tag_name) | ||||
|           socket |> put_flash(:info, prompt) |> push_redirect(to: return_to) | ||||
|  | ||||
|         {:error, %Changeset{} = changeset} -> | ||||
|         {:noreply, socket |> assign(changeset: changeset)} | ||||
|           socket |> assign(:changeset, changeset) | ||||
|       end | ||||
|  | ||||
|     {:noreply, socket} | ||||
|   end | ||||
|  | ||||
|   defp save_tag( | ||||
|          %{assigns: %{current_user: current_user, return_to: return_to}} = socket, | ||||
|          :new, | ||||
|          tag_params | ||||
|        ) do | ||||
|     socket = | ||||
|       case Tags.create_tag(tag_params, current_user) do | ||||
|         {:ok, %{name: tag_name}} -> | ||||
|           prompt = dgettext("prompts", "%{name} created successfully", name: tag_name) | ||||
|           socket |> put_flash(:info, prompt) |> push_redirect(to: return_to) | ||||
|  | ||||
|         {:error, %Changeset{} = changeset} -> | ||||
|           socket |> assign(changeset: changeset) | ||||
|       end | ||||
|  | ||||
|     {:noreply, socket} | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -14,14 +14,14 @@ defmodule CanneryWeb.TagLive.Index do | ||||
|   end | ||||
|  | ||||
|   @impl true | ||||
|   def handle_params(params, _url, socket) do | ||||
|     {:noreply, apply_action(socket, socket.assigns.live_action, params)} | ||||
|   def handle_params(params, _url, %{assigns: %{live_action: live_action}} = socket) do | ||||
|     {:noreply, apply_action(socket, live_action, params)} | ||||
|   end | ||||
|  | ||||
|   defp apply_action(socket, :edit, %{"id" => id}) do | ||||
|   defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do | ||||
|     socket | ||||
|     |> assign(:page_title, gettext("Edit Tag")) | ||||
|     |> assign(:tag, Tags.get_tag!(id)) | ||||
|     |> assign(:tag, Tags.get_tag!(id, current_user)) | ||||
|   end | ||||
|  | ||||
|   defp apply_action(socket, :new, _params) do | ||||
| @@ -31,21 +31,19 @@ defmodule CanneryWeb.TagLive.Index do | ||||
|   end | ||||
|  | ||||
|   defp apply_action(socket, :index, _params) do | ||||
|     socket | ||||
|     |> assign(:page_title, gettext("Listing Tags")) | ||||
|     |> assign(:tag, nil) | ||||
|     socket |> assign(:page_title, gettext("Listing Tags")) |> assign(:tag, nil) | ||||
|   end | ||||
|  | ||||
|   @impl true | ||||
|   def handle_event("delete", %{"id" => id}, socket) do | ||||
|     tag = Tags.get_tag!(id) | ||||
|     {:ok, _} = Tags.delete_tag(tag) | ||||
|     socket = socket |> put_flash(:info, dgettext("prompts", "Tag deleted succesfully")) | ||||
|     {:noreply, socket |> display_tags()} | ||||
|   def handle_event("delete", %{"id" => id}, %{assigns: %{current_user: current_user}} = socket) do | ||||
|     %{name: tag_name} = Tags.get_tag!(id, current_user) |> Tags.delete_tag!(current_user) | ||||
|  | ||||
|     prompt = dgettext("prompts", "%{name} deleted succesfully", name: tag_name) | ||||
|  | ||||
|     {:noreply, socket |> put_flash(:info, prompt) |> display_tags()} | ||||
|   end | ||||
|  | ||||
|   defp display_tags(socket) do | ||||
|     tags = Tags.list_tags(socket.assigns.current_user) | ||||
|     socket |> assign(tags: tags) | ||||
|   defp display_tags(%{assigns: %{current_user: current_user}} = socket) do | ||||
|     socket |> assign(tags: Tags.list_tags(current_user)) | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -95,7 +95,7 @@ msgstr "" | ||||
| #: lib/cannery_web/live/ammo_type_live/form_component.ex:155 | ||||
| #: lib/cannery_web/live/container_live/form_component.ex:79 | ||||
| #: lib/cannery_web/live/invite_live/form_component.ex:61 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:70 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:69 | ||||
| msgid "Save" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -305,7 +305,7 @@ msgstr "" | ||||
| #: lib/cannery_web/live/ammo_type_live/index.html.heex:26 | ||||
| #: lib/cannery_web/live/container_live/form_component.ex:49 | ||||
| #: lib/cannery_web/live/invite_live/form_component.ex:53 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:54 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:53 | ||||
| msgid "Name" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -451,7 +451,7 @@ msgid "Type:" | ||||
| msgstr "" | ||||
|  | ||||
| #, elixir-format, ex-autogen | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:58 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:57 | ||||
| msgid "Background color" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -523,7 +523,7 @@ msgid "Tags can be added to your containers to help you organize" | ||||
| msgstr "" | ||||
|  | ||||
| #, elixir-format, ex-autogen | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:64 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:63 | ||||
| msgid "Text color" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -98,7 +98,7 @@ msgstr "" | ||||
| #: lib/cannery_web/live/ammo_type_live/form_component.ex:156 | ||||
| #: lib/cannery_web/live/container_live/form_component.ex:81 | ||||
| #: lib/cannery_web/live/invite_live/form_component.ex:63 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:72 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:71 | ||||
| msgid "Saving..." | ||||
| msgstr "" | ||||
|  | ||||
| @@ -152,16 +152,16 @@ msgid "Invite updated successfully" | ||||
| msgstr "" | ||||
|  | ||||
| #, elixir-format, ex-autogen | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:100 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:98 | ||||
| msgid "Tag created successfully" | ||||
| msgstr "" | ||||
|  | ||||
| #, elixir-format, ex-autogen | ||||
| #: lib/cannery_web/live/tag_live/index.ex:43 | ||||
| #: lib/cannery_web/live/tag_live/index.ex:45 | ||||
| msgid "Tag deleted succesfully" | ||||
| msgstr "" | ||||
|  | ||||
| #, elixir-format, ex-autogen | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:84 | ||||
| #: lib/cannery_web/live/tag_live/form_component.ex:83 | ||||
| msgid "Tag updated successfully" | ||||
| msgstr "" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user