Elixir Digitalization Implementors/fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます
前回は、Phoenixのphx.gen.html/phx.gen.jsonで生成されるDBアクセッサの「論理削除」を実装したので、今回は、削除UIの論理削除トグル化の対応を行います
内容が、面白かったり、役に立ったら、「LGTM」よろしくお願いします
Advent Calendar、fukuoka.ex1位、Elixir2位達成ヽ(=´▽`=)ノ
fukuoka.ex Advent Calendar、Webテクノロジーカテゴリで堂々1位 … 各コラムぜひお読みください
https://qiita.com/advent-calendar/2020/fukuokaex
そして、プログラミング言語カテゴリは、1位がRust、2位がElixir、3位がGoとモダン言語揃い踏みでのトップ3、熱いネー
https://qiita.com/advent-calendar/2020/elixir
本コラムの検証環境
本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)
- Windows 10
- Elixir 1.11.3 ※最新版のインストール手順はコチラ
- Phoenix 1.5.7 ※最新版のインストール手順はコチラ
- PostgreSQL 10.1 ※最新版のインストール手順はコチラ
削除UIの論理削除対応
一覧UIのDeleteリンクが、前回の対応により、物理削除から、論理削除に変更されていますが、一度Deleteした後は、論理削除状態を解除して、元に戻すことができないUIになっています
これを、論理削除状態をトグル化するために、コントローラを改修します
改修前のコントローラは、以下の通りです
defmodule BasicWeb.PostController do
use BasicWeb, :controller
…
def delete(conn, %{"id" => id}) do
post = Posts.get_post!(id)
{:ok, _post} = Posts.delete_post(post)
conn
|> put_flash(:info, "Post deleted successfully.")
|> redirect(to: Routes.post_path(conn, :index))
end
…
これを以下のように、対象データの論理削除状態で、呼び出す関数と、実行後のメッセージをスイッチするように改修します
def delete(conn, %{"id" => id}) do
post = Posts.get_post!(id)
# {:ok, _post} = Posts.delete_post(post) # Comment-out here
# Add start
action = case post.deleted_at do
nil -> %{ target: "deleted", func: &Posts.delete_post/1 }
_ -> %{ target: "delete restored", func: &Posts.restore_delete_post/1 }
end
{:ok, _post} = action.func.( post )
# Add end
conn
# |> put_flash(:info, "Post deleted successfully.") # Comment-out here
|> put_flash(:info, "Post #{ action.target } successfully.") # Add here
|> redirect(to: Routes.post_path(conn, :index))
end
一覧UIのDeleteリンク文言も、論理削除状態でスイッチするようにします
…
<%= for post <- @posts do %>
<% logical_delete = if post.deleted_at == nil, do: "Delete", else: "Restore" # Add here %>
<tr>
<td>
<span><%= link "Show", to: Routes.post_path(@conn, :show, post) %></span>
<span><%= link "Edit", to: Routes.post_path(@conn, :edit, post) %></span>
<!-- <span> --><%= # Comment-out after link "Delete", to: Routes.post_path(@conn, :delete, post), method: :delete, data: [confirm: "Are you sure?"] %><!-- </span> -->
<span><%= link logical_delete, to: Routes.post_path(@conn, :delete, post), method: :delete, data: [confirm: "Are you sure?"] %></span> <!-- Add here -->
</td>
</tr>
<% end %>
…
これで、Deleteリンクをクリックすると、下記の通り、deleted_atに現在日時(UTC)が入り、DeleteリンクがRestoreリンクにスイッチするようになります
Restoreリンクをクリックすると、deleted_atが空(nil)になり、RestoreリンクがDeleteリンクに戻ります
最後に
今回は、削除UIの論理削除トグル化を行いました
Elixir開発の実務でも良く出てくるテクニックなので、覚えておきましょう
次回は、一覧/個別表示UIでの論理削除時グレーアウト表示切り替えを行います