【2021年から Ruby on Rails をはじめる人向け】 Ruby on Rails 6 入門 Part 7 ~ Rails でバリデーションチェックを自動で行う方法~

link です。
今回は Rails 上でバリデーションチェックを行う方法について勉強していきます。
この記事は Ruby on Rails 6 入門 Part 6 の続きです。
前提条件
- Windows 10
- Ruby 3
- Ruby on Rails 6
バリデーションチェック
前回紹介した Active Record にはバリデーション機能が備わっています。
この機能を使って、オブジェクトが保存される前にオブジェクトの状態を検証する方法を勉強していきましょう。
app/model/Person.rb を開いて、以下のように書き換えます。
class Person < ApplicationRecord
validates :name, presence: true
endこれは、モデルのオブジェクトを保存するときにバリデーションを行うプロパティーを指定しています。
上述の例では、 Person モデルの name プロパティーを指定しています。
続けて、 app/controller/people_controller.rb の create メソッドを以下のように書き換えます。
def create
if request.post? then
if Person.create(person_params).valid? then
redirect_to '/people/index'
else
@msg = "Name が入力されていません"
render 'add'
end
end
endいつものように rails s で Web アプリを起動させたうえで localhost:3000/people/add にアクセスして、何も入力せずに Save ボタンを押しましょう。
ボタンが Create Person から Save に変わっていますが、動作に問題はありません。
どうしても気になる場合は app/views/people/add.html.erb を書き換えましょう。
以下の文を書き換えます。
<%= form.submit class:"btn btn-primary" %>これで常時、 作成 ボタンが表示されます。
<%= form.submit "作成", class:"btn btn-primary" %>上述の例を用いて解説していきます。
Person.create を実行すると、モデル内に記述された validetes の内容に基づいて、データベースにオブジェクトを保存するかを決定します。
オブジェクトが保存されたか否かは valid? プロパティーで取得できます。
valid? プロパティーが true なら、オブジェクトを保存後、people/index に画面を遷移します。
false なら、オブジェクトを保存せず、 @msg にエラーメッセージを表示させています。
バリデーションヘルパー
Active Record には、モデル内で直接使える定義済みのバリデーションヘルパーが多数用意されています。
その中からいくつか紹介します。
acceptance
チェックボックスにチェックが入っているかを確認します。
class Person < ApplicationRecord
validates :check, acceptance: true
endView テンプレートで生成されたチェックボックスのオプションがバリデーションチェックの対象になります。
そのため、データベース上に対応するカラムを作る必要はありません。
<%= f.check_box :check %>confirmation
2 つのテキストフィールドで受け取る内容が完全に一致する必要がある場合に使います。
たとえば、 name を確認したい場合はモデルのバリデーションに confirmation を設定したうえで、View テンプレートに _confirmation がついた項目を用意します。
class Person < ApplicationRecord
validates :name, confirmation: true
end<%= text_field :person, :name %>
<%= text_field :person, :name_confirmation %>このチェックは、 name_confirmation が nil でない場合のみ行われます。
確認を必須にするには、後述する presence を使って、確認用の項目についての存在チェックも追加してください。
length
入力値の長さに基づいて、バリデーションチェックを行うヘルパーです。
class Person < ApplicationRecord
validates :name, length: { minimum: 2 }
end以下のオプションが存在します。
minimum: 入力された文字列の長さの下限を設定します。maximum: 入力された文字列の長さの上限を設定します。inまたはwithin: 入力された文字列の長さが、与えられた区間以内であるかを確認します。is: 入力された文字列の長さが設定された値と等しいかを確認します。
numericality
入力値が数値かどうかをチェックするヘルパーです。
整数のみかどうかをチェックしたい場合は true の代わりに { only_integer: true } を記述しましょう。
only_integer が true でない場合の値の型は Float として扱われます。
class Person < ApplicationRecord
validates :age, numericality: true
endpresence
指定された属性が「空でない」こと (nil でない ) を確認します。
class Person < ApplicationRecord
validates :name, presence: true
endabsence
presence とは逆に、指定された属性が「空である」こと (nil である ) を確認します。
class Person < ApplicationRecord
validates :name, absence: true
enduniqueness
このヘルパーは、データベースにオブジェクトを保存する前に、保存する値がデータベース上のレコードと重複していないことをチェックします。
class Person < ApplicationRecord
validates :name, uniqueness: true
endカスタムバリデーション
既存のバリデーションヘルパーでは足りない場合、自分でバリデーションを作ることもできます。
カスタムバリデーションを作る場合は ActiveModel::Validator を継承したクラスを作ります。
これらのクラスには validate メソッドを実装する必要があります。
validate メソッドはレコードを 1 つ引数に取り、それに対してバリデーションを実行します。
カスタムバリデーションは validates_with メソッドを使って呼び出します。
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.name.starts_with? 'X'
record.errors[:name] << '名前は X で始まる必要があります'
end
end
end
class Person < ApplicationRecord
include ActiveModel::Validations
validates_with MyValidator
endバリデーションエラー
Active Record では、バリデーションが失敗するたびに、オブジェクトの errors コレクションにエラーメッセージが追加されます。
試しに直打ちのエラーメッセージではなく、 errors コレクションのエラーメッセージを表示させてみましょう。
app/controllers/people_controller.rb の add メソッドと create メソッドを以下のように変更します。
def add
@msg = "add new data."
@person = Person.new
@errors = Hash.new
end
def create
if request.post? then
person = Person.create(person_params)
if person.valid? then
redirect_to '/people/index'
else
@errorMessages = person.errors
render 'add'
end
end
end続いて、 app/views/people/add.html.erb を以下のように変更します。
<h1 class="display-4 text-primary">People#add</h1>
<p><%= @msg %></p>
<% @errorMessages.values.each do |error| %>
<p><%= error %></p>
<% end %>
<%= form_with model: @person, url: people_add_path do |form| %>
<div class="form-group">
<label for="name">Name</label>
<%= form.text_field :name, class:"form-control" %>
</div>
<div class="form-group">
<label for="age">Age</label>
<%= form.text_field :age, class:"form-control" %>
</div>
<%= form.submit class:"btn btn-primary" %>
<% end %>最後に app/models/person.rb を以下のように変更します。
class Person < ApplicationRecord
validates :name, presence: {message: "Name が入力されていません"}
validates :age, presence: {message: "Age が入力されていません"}
validates :age, numericality: {only_integer: true, message: "数値ではありません"}
endlocalhost:3000/people/add で何も入力せずに Save ボタンを押しましょう。
errorMessages に保存されるエラーメッセージは以下のような連想配列になっています。
{
:name => ["Name が入力されていません"],
:age => ["Age が入力されていません", "数値ではありません"]
}バリデーションチェックの対象となる値をキーとして、バリデーションチェックに引っかかった条件のエラーメッセージの配列を保存しています。
カスタムメッセージ
上述の例の通り、バリデーションヘルパーの message オプションを指定すれば任意のエラーメッセージを表示させることができます。
class Person < ApplicationRecord
validates :name, presence: {message: "Name が入力されていません"}
end参考サイト
Active Record バリデーション - Railsガイド
まとめ
今回は Active Record バリデーションを使って Rails 上でバリデーションチェックを行う方法を勉強しました。
次回は Rails のモデル連携(アソシエーション)について勉強します。
それではまた、別の記事でお会いしましょう。




