LoginSignup
17
2

More than 3 years have passed since last update.

Elixirでバリデーションを実装してみた

Last updated at Posted at 2020-12-14

この記事は、fukuoka.ex Elixir/Phoenix Advent Calendar 2020 14日目です。

前日は、 @piacerex さんの [書評] プログラミングElixir第2版のインプレッションとアップデート でした

Elixirでバリデーションを実装してみた:rainbow:

@tuchiro さんのこちらの記事の手順に沿って進めました。

DBラッパーEctoのchangesetでお手軽入力チェック
https://qiita.com/tuchiro/items/de56e38efa8c397abdff
(※環境構築のみ元記事のPhoenix 1.3から現行最新版のPhoenix 1.5に変更、以降は記事通りの手順です)

実装の概要:writing_hand:

  • PhoenixのSSR(Server Side Rendering)であるEExでユーザー登録を行うWebアプリを実装する。
  • Webアプリは、PhoenixのWeb CRUD自動生成コマンドで構築する
  • DBはデフォルトのPostgreSQLを選択する。
  • Ecto.Changesetで入力チェックを行う。

バリデーション仕様は以下の通り

  • 必須項目チェックの内容をカスタマイズする
  • パスワードの桁範囲、許容文字チェックを行う(パスワードのハッシュ化については別の記事が参考になるので割愛)
  • 電話番号が全角入力されたら自動的に半角変換する
  • emailアドレスが正しい書式かフォーマットをチェックする
  • コード値項目は事前に定義したメンバーと一致するか妥当性チェックを行う。
  • メールアドレスを業務的なユニークキーとして、重複チェックを行う。

完成したもの:sparkles::sparkles:

以下コマンドで環境構築後、元記事の「depsにMojiexを追加」以降をそのまま進めると、バリデーションがかかるようになりました。

$mix phx.new ecto_changeset_sample
$cd ecto_changeset_sample
$mix ecto.create

下記の通り、不正な値を入力して、SAVEボタンを押下すると、バリデーションエラーが表示されます。

スクリーンショット 2020-12-14 18.35.16.png

実装箇所(changesetの内容):computer:

lib/ecto_changeset_sample/accounts/user.exをカスタマイズ

  @doc false
  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :age, :email, :password, :phone_number, :grade, :resident_type])
    |> validate_required([:name, :age, :email, :password, :grade])
    |> validate_length(:password, min: 8, max: 16)
    |> validate_format(:password, ~r/\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[a-zA-Z\d]/)
    |> validate_confirmation(:password, message: "does not match password")
    |> put_change(:phone_number, Mojiex.convert(attrs["phone_number"],{:ze,:he}))
    |> validate_length(:phone_number, min: 10, max: 11)
    |> validate_format(:phone_number, ~r/[0-9]{10,11}/)
    |> validate_format(:email, ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
    |> validate_inclusion(:grade, Map.values(grade()))
    |> validate_inclusion(:resident_type, Map.values(resident_type()))
    |> unique_constraint(:email)
  end
end
  • validate_required は必須チェック(全項目必須適用になっている)
  • validate_length で文字長の範囲チェック
  • validate_format で正規表現チェック
  • validate_confirmation で確認入力チェック(主にパスワード用)
  • put_change を使えば、半角全角大文字小文字など文字揺らぎの自動変換も可能
  • validate_inclusion で選択肢の妥当性チェック(数字の範囲などもチェック可能) (tuchiroさんの記事より抜粋)

バリデーションは実装できましたが、大元のchangesetについては、
時間が足りず調べられなかった為、次の記事を読んで学びたいと思います。

elixirschool チェンジセット
https://elixirschool.com/ja/lessons/ecto/changesets/

手順以外で実施したこと:bulb:

PostgreSQLインストール

How to Install and Configure PostgreSQL Server on macOS Mac OS X
↑↑こちらの動画は @piacerex さんにご紹介頂きました。
説明が丁寧でわかりやすく、導入後も使いやすいと思いました。

Phoenix起動時、cryptoライブラリロードエラーが出た

次のエラーが表示されました。

スクリーンショット 2020-12-14 21.53.38.png
(エラーは、下記の @takasehideki さんの記事と同じものです。)
macOS CatalinaでErlang 22.2がビルドできない時の対処法

【対処方法】 以下のElixir/Erlangバージョンに上げた

  • Elixir-1.11.2
  • Erlang-23.1.5

【ポイント:bulb:
エラーの原因は、環境の差異、Elixir/Erlangのバージョンが古い為によるもので、
数年前の記事などを参考にする場合は、新しいバージョンに更新した方が良いようです。

asdfでerlang install,brew update失敗など、色々あり・・・
asdfをアンインストールして、brew自体を入れ直してなんとかなりました。
asdfのアンインストール手順はこちら
Homebrewのアンインストール手順はこちら
Phoenixのアンインストール/インストールの手順はこちら

Node.jsインストール

Ecto.Repoのコンパイルでエラーが出た

次のエラーが表示されました。
スクリーンショット 2020-12-14 20.07.16.png
【対処方法】 下記コマンドを実行

$export MIX_ENV=dev
$mix deps.get
$mix ecto create

【ポイント:bulb:
エラーの原因は、Ectoアダプターの設定が無いとのことで、Elixir PJの起動環境が、
以前実施したProdのままになっていたようなので、devに戻しました。

DB接続エラーが出た

次のエラーが表示されました。

DBConnection.ConnectionError
(Mix) The database for EctoChangesetSample.Repo couldn’t be created: killed`

【対処方法】 下記ウインドウを出し、PostgreSQLを起動

スクリーンショット 2020-12-14 21.44.12.png

【ポイント:bulb:
エラーの原因は、PostgreSQLが起動していなかった為で、起動したら、動くようになりました。

テーブル重複エラーが出た

スクリーンショット 2020-12-15 0.19.18.png

【対処方法】 下記コマンドを実行

$mix ecto.migrate --step 1

【ポイント:bulb:
エラーの原因は、PJを作り直す前にmigrateしてテーブル作成済のところに、再度migrateした為で、
migrateのステップを先頭からやり直したら上手くいきました。

以下を参考にしました。

mix ecto.migrate で重複エラーが起きた時のメモ【調査中】
https://qiita.com/VA-11_Hall-A/items/a8fe72835108ea612d16

感想

環境の部分に時間を多く取られてしまった為、数をこなして、エラーの原因の切り分けをできるようになっていきたいと思いました。
チェンジセットや正規表現については、勉強して今後実装を試していきたいと思います。
環境により、結果やエラーの内容は変わると思いますが、こちらの記事がどなたかの参考になりましたら幸いです。

最後に
@piacerex さん、今回環境周りで詰まっておりましたところ、丁寧に質問に答えてくださり、本当にありがとうございました。:bow:
Elixirコミュニティの皆さま、エリジョ(Elixir女子部)や勉強会にて、2020年は大変お世話になりました。
いつもご親切にありがとうございます。:relaxed:

明日は @piacerex さんの「WSL2でElixir本体のビルドとiexバージョン変更」 です! お楽しみに!:rocket:

17
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
2