📖

【Rails】フォームバリデーションの実装(モデルバリデーションとの違いも)

2024/04/11に公開

はじめに

フォームバリデーション(フォームオブジェクト、フォーム検証、Forms Validation)を実装する機会がありました。フォームバリデーションの実装に至った経緯やモデルバリデーションとの違いなどを踏まえ、メモ書きとして共有します。

なぜフォームにバリデーションを書くのか

https://qiita.com/k-mashi/items/b2faf37cd991ee396f00
こちらの記事から引用すると、

フォームバリデーションはユーザーの入力した値に対して適切か検証する際、バリデーションを...

  • コントローラーにバリデーションを書くとコードが複雑になる
  • モデルに書くとフォーム固有のロジックで煩雑になる
  • バリデーション専用クラスを作り、ロジックを集約することで解決しよう!

というイメージです。

モデルとフォームオブジェクトの違い

モデルバリデーションは、データベースに保存されるデータが正しい形式であることを保証するために使用されます。これは、アプリケーションのデータの整合性を維持するために重要です。

一方で、フォームバリデーションは、ユーザーからの入力を直接検証するために使用されます。これは、特定のフォームに特有のバリデーションルールを適用する場合や、複数のモデルにまたがる複雑なデータの入力を処理する場合に特に有効です。

フォームバリデーション実装までの経緯

Webアプリケーションにおいて、ユーザーからの入力を受け取るフォームは、情報の収集や機能の実行に不可欠です。しかし、不正確または不適切な入力がシステムに渡されると、エラーの原因となり、場合によってはシステムが停止したり、セキュリティリスクを高めることにもなります。

直面した具体的なシーンとして、人数を入力するカラムに対してNullが許容されている部分が存在しており、上記のシステム上の懸念があるのではないかということでチームと相談し、フォームバリデーションを実装することが決まりました。

フォームバリデーションの要件

ビジネスチームと話し合い、以下のフォームバリデーションの要件に決まりました。

許容

  • 0以上の整数
  • 半角数字とする

許容しない

  • Null
  • 全角数字
  • 文字

さらに

  • デフォルト値を(Nullではなく)0に設定してしまう
  • 許容しない場合にはエラーメッセージを記載するネガティブな言葉は使用しないように注意する

https://f-tra.com/ja/blog/column/5995

実装

以下は、ある数値入力フィールド(max_users)が上記の要件を満たすフォームバリデーションを追加します。max_usersの値が有効な数字でない場合に、is_validをfalse(入力データをpathさせないよう)に設定します。

is_valid = false unless max_users_valid?(data['max_users'], field)

また、max_users_valid?メソッドは、max_usersの値が0以上の整数であるかどうかを検証します。

def max_users_valid?(max_users, field)
  parsed_users = max_users.to_i
  
  if max_users.blank? || max_users.to_s != parsed_users.to_s || parsed_users.negative?
    errors.add(field, ': max_usersは0以上の数字を入力してください。')
    @is_valid = false
    return false
  end

  true
end

このメソッドでは、まずmax_usersを整数に変換し、その後3つの条件をチェックします。

if max_users.blank? || max_users.to_s != parsed_users.to_s || parsed_users.negative?
  1. max_usersが空であるか
  2. 文字列としてのmax_usersと整数に変換した後の値が不一致か(つまり、元の値が整数でないか)→ 不一致例:(123abc≠123)
  3. または負の数であるかを検証します。
errors.add(field, ': max_usersは0以上の数字を入力してください。')
    @is_valid = false

いずれかの条件が当てはまる、すなわちtrueの場合、エラーメッセージが「max_usersは0以上の数字を入力してください。」と表示され、is_validがfalseに設定されます。

動作確認

SequleAceを使用し、Local環境に保存されたユーザーの該当するカラムを確認しました。
結果、Nullがなくなり、要件通りに実装できました。(フォームバリデーション以外にも実装部分あり)

https://github.com/Sequel-Ace/Sequel-Ace

https://qiita.com/ucan-lab/items/b1304eee2157dbef7774

まとめ

フォームバリデーションは、ユーザーからの入力を正しく受け取るために重要です。この記事では、不正確な入力を防ぐためにフォームバリデーションを実装した経緯、モデルバリデーションとの違い、そして具体的な実装方法について解説しました。最終的に、要件に合ったバリデーションを実装し、システムの信頼性を高められたと思います。

参考

https://railsguides.jp/active_record_validations.html

https://qiita.com/h1kita/items/772b81a1cc066e67930e

https://qiita.com/k-mashi/items/b2faf37cd991ee396f00

https://developer.mozilla.org/ja/docs/Learn/Forms/Form_validation

Discussion