Phoenix1.7 DBに投入データスクリプト作成

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はPhoenix1.7でDBにデータを投入するスクリプトを作成しました。

# 目的
Phoenix1.7でDBに1件または複数件のデータを投入するスクリプトを作成する。

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.14.3
Phoenix v1.7.2
※piyopiyoというプロジェクト名でPhoenixプロジェクトを作成後、`mix phx.gen.live User User users name:string age:integer`を実行してルーティング追加およびmigrationまで実施済。

# Phoenix1.7でDBにデータが追加される処理順の確認
## エンドポイント/users内のNew Userボタンを押下したとき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677280/c152a0bd-f12d-796c-bf6f-a44fd80dfdab.png)

PiyopiyoWeb.UserLive.FormComponentの :newを呼び出す。
```elixir:lib/piyopiyo_web/live/user_live/index.html.heex
<.modal :if={@live_action in [:new, :edit]} id="user-modal" show on_cancel={JS.patch(~p"/users")}>
  <.live_component
    module={PiyopiyoWeb.UserLive.FormComponent}
    id={@user.id || :new}
    title={@page_title}
    action={@live_action}
    user={@user}
    patch={~p"/users"}
  />
</.modal>
```

Userを新規登録するためのモーダルをrenderする。
```elixir:lib/piyopiyo_web/live/user_live/form_component.ex
def render(assigns) do
    ~H"""
    <div>
      <.header>
        <%= @title %>
        <:subtitle>Use this form to manage user records in your database.</:subtitle>
      </.header>

      <.simple_form
        for={@form}
        id="user-form"
        phx-target={@myself}
        phx-change="validate"
        phx-submit="save"
      >
        <.input field={@form[:name]} type="text" label="Name" />
        <.input field={@form[:age]} type="number" label="Age" />
        <:actions>
          <.button phx-disable-with="Saving...">Save User</.button>
        </:actions>
      </.simple_form>
    </div>
    """
  end
```
## モーダルのフォーム内にバリデーション上有効なNameとAgeを記載後、Save Userボタンを押下したとき
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677280/08be4fcd-abf7-8bdb-7567-669c806caacb.png)

Users.create_userを呼び出し、DBに追加する処理を行う。
```elixir:lib/piyopiyo_web/live/user_live/form_component.ex
def handle_event("save", %{"user" => user_params}, socket) do
    save_user(socket, socket.assigns.action, user_params)
end
#------中略------

defp save_user(socket, :new, user_params) do
    case Users.create_user(user_params) do
      {:ok, user} ->
        notify_parent({:saved, user})
    
        {:noreply,
         socket
         |> put_flash(:info, "User created successfully")
         |> push_patch(to: socket.assigns.patch)}
    
      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, assign_form(socket, changeset)}
    end
end
```

```elixir:lib/piyopiyo/users.ex
def create_user(attrs \\ %{}) do
    %User{}
    |> User.changeset(attrs)
    |> Repo.insert()
end
```
DBにデータが追加された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677280/5ec5cdcf-a97f-91e4-510f-bb2f00abb1a3.png)


# 以上を踏まえてデータスクリプト作成
## 1件データを追加するスクリプト
```elixir:priv/repo/seeds.exs
  alias Piyopiyo.Users

  Users.create_user(
    %{"age" => "1", "name" => "Mike"}
  )
```

#### スクリプトの実行
```bash:shell
mix run priv/repo/seeds.exs
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677280/fa1086f6-3d6d-91d0-e7d2-1764a38cd321.png)


##  複数件データを追加するスクリプト
```elixir:priv/repo/seeds.exs
#データ投入する関数
  alias Piyopiyo.Users

  defmodule ListUtils do
    def create_users([]) do
    end
    def create_users([head | tail]) do
      Users.create_user(head)
      create_users(tail)
    end
  end

# 投入するデータをマップリストの形でここに書く
   list = [
     %{"age" => 20, "name" => "Alice"},
     %{"age" => 35, "name" => "Bob"},
     %{"age" => 49, "name" => "Candy"}
   ]

#複数件データ投入を実行
  ListUtils.create_users(list)
```

#### スクリプトの実行
```bash:shell
mix run priv/repo/seeds.exs
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677280/38e7079c-3c42-0c15-c10e-9459c12d2b79.png)


# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！