LoginSignup
0
0

More than 3 years have passed since last update.

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

Posted at

モデル検証の概要

データの内容の範囲をデータベースで定義することで、保存に制約をかけることができます。
それ以外にも、制約をモデル(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速習実践ガイド

0
0
0

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
0
0