search
LoginSignup
0

More than 1 year has passed since last update.

posted at

【Rails】モデルの検証の実装

モデル検証の概要

データの内容の範囲をデータベースで定義することで、保存に制約をかけることができます。
それ以外にも、制約をモデル(Rubyコード)でチェックできたり、違反した場合のエラーメッセージを返すこともできます。データの内容のチェックは検証(Validation)と言い、RailsのモデルもRubyコードによって検証をする仕組みがあります。モデルの検証により、自由度の高いチェックとともに、エラーを伝えやすくできます。

モデル検証の仕組み

Railsにおけるモデルの検証は「オブジェクトをDBに保存・更新する前に検証を行い、エラーがあれば登録・更新をしないで差し戻す」という仕組みです。この仕組みに対応するメソッドがsaveです。

検証の書き方

検証コードは自分で記述する方法と、Railsが備えるヘルパーを利用する2通りがあります。後者でよく使われるのが以下の検証機能です。

検証内容 ヘルパーの使い方の例
必須のデータが入っているか? validates :foo, presence: true
数値以外が入っていないか?小数点の有無・正負が期待通りか? validates :foo, numericality: true
数値の範囲が期待通りか? validates :foo, inclusion: { in: 0..9}
文字列の長さが想定どおりか? validates :foo, length: { maximum: 30}
文字列のフォーマットや構成文字種が想定通りか? validates :foo, format: { with: ・・・} validates :foo, inclusion: {in: ・・・}
データが一意になっているか? validates :foo, uniqueness: true
パスワードやメールアドレスが、その確認用の入力と一致しているか? validates :foo, confirmation

モデルへの検証の追加(必須かどうかの検証)

作成したアプリのPostモデルのcontent属性の値が入っていなければ検証エラーになるように、検証を追加します。

app/models/post.rb
class Post < ApplicationRecord
  validates :content, presence: true
end

コントローラーの変更

次に、Postモデルが検証に引っかかった際にユーザーにわかりやすく表示し際入力を促す必要があります。まずは、コントローラーに変更を加えます。以前のcreateアクションを…

app/controllers/posts_controller.rb
  def create
    post = Post.new(post_params)
    post.save!
    redirect_to posts_url, notice: "「#{post.content}」を投稿しました。"
  end

次のように変更します。

app/controllers/posts_controller.rb
  def create
    @post = Post.new(post_params)

    if @post.save
      redirect_to @post, notice: "「#{@post.content}」を投稿しました。"
    else
      render :new
    end
  end

投稿に用いるメソッドをsave!からsaveに変更しました。検証によりユーザーの入力次第で、投稿に失敗するするようになりました。そこで、失敗時に処理を中断してしまうsave!ではなく、例外を発生させるsaveにより戻り値を取得し、制御を変えるようにしています。
検証エラー次の処理を追加しました。検証結果がfalseだった場合、render :newによって投稿フォーム画面を再表示させ、際入力を促します。
Postオブジェクトをインスタンス変数に代入させました。エラー時に投稿画面を再表示させる際に、ビューに検証を行った現物のPostオブジェクトを渡す必要があるからです。@postをビューに伝えることで、次の2点の効果が生まれます。

  1. 前回入力したままのデータがフォームに入った状態を引き継いで表示できる。
  2. Postオブジェクトが抱える検証エラーの内容をユーザーに表示できる。

ビューの変更

続いてビューの変更を行ます。
検証エラーメッセージを表示するため、form_withの上にメッセージ領域を作成します。

app/views/posts/_form.html.slim
- if post.errors.present?
  ul#error_explanation
    - post.errors.full_messages.each do |message|
      li= message

= form_with model: post, local: true do |f|
  

errors.present?で検証エラーの有無を調べ、エラーがある時にエラーメッセージを表示するようにしています。
A6356AAF-C034-475D-B91C-72928B05CFEA_1_105_c.jpeg

モデル検証の追加(文字列の長さの検証)

DBの定義でcontentカラムの文字列を50文字以下に制限したので、ユーザーにわかるよう検証エラーを実装します。
validatesは、同じ属性に対して複数の検証を1行に書くことができます。

app/models/post.rb
class Post < ApplicationRecord
  validates :content, presence: true, length: { maximum: 50 }
end

61B73BD0-681C-4962-9C5F-0BF2E440D65E_1_105_c.jpeg

参考

現場で使える Ruby on Rails 5速習実践ガイド

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
What you can do with signing up
0