Railsのバリデーションでチェックしてみる

RailsをMySQLに対応させてみるの続き
RailsのMySQLの環境にアクセスできるようにしておくも済ませておく)

RailsのバリデーションでModelの値をチェックしてみる。


とりあえずUserのモデルとテーブルを作っておく。

$ rails generate model user name:string gender:integer category:integer flag:boolean comment:text
$ rake db:migrate

バリデーションを指定せず保存

とりあえず、バリデーションを指定せず、保存してみる。

$ vi app/controllers/sample_controller.rb
class SampleController < ApplicationController
  def index
    user = User.new(name: '', gender: 'a', category: 4, flag: true, comment: 'a')
    result = user.save
    render :json => user.errors
  end
end

ブラウザでアクセスすると、下記のように表示され、DBに保存される。

{}

バリデーションを指定して保存

次にバリデーションを指定する。

$ vi app/models/user.rb
class User < ActiveRecord::Base
  validates :name, presence: true                        # 値が設定されているかどうか
  validates :gender, numericality: true                  # 数値かどうか
  validates :category, inclusion: {in: 1..3 }            # 値が1〜3の範囲内かどうか
  validates :comment, length: {minimum: 2, maximum: 4}   # 文字列の長さが2文字以上、4文字以下かどうか
end

ブラウザでアクセスすると、下記のように表示される。
(見やすいように改行入れてますが、実際は一行で表示されています。)

{
"name":["can't be blank"],
"gender":["is not a number"],
"category":["is not included in the list"],
"comment":["is too short (minimum is 2 characters)"]
}

下記のようにパラメタの値を修正し、

$ vi app/controllers/sample_controller.rb
class SampleController < ApplicationController
  def index
    user = User.new(name: 'tarou', gender: 1, category: 3, flag: true, comment: 'aa')
    result = user.save
    render :json => user.errors
  end
end

ブラウザでアクセスすると、エラーにならず、DBに保存される。

{}

独自バリデーション

appの下にvalidatorsのディレクトリを作成する。

$ mkdir app/validators
「app/validators/」にvalidatorのファイルを置くと、勝手にロードされるらしい

【参考】
validation - Where should Rails 3 custom validators be stored? - Stack Overflow
http://stackoverflow.com/questions/5263239/where-should-rails-3-custom-validators-be-stored

validatorのファイルを作成する。
今回は、「tarou」という文字列が指定されているとエラーになるvalidatorを作ってみる。

$ vi app/validators/ng_word_validator.rb
class NgWordValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if value == 'tarou'
      record.errors[attribute] << "#{attribute}#{value}は指定しないでください!!!"
    end
  end
end

Modelにng_wordのvalidatorを指定する。

$ vi app/models/user.rb
class User < ActiveRecord::Base
  validates :name, ng_word: true
end

ブラウザでアクセスすると、下記のように表示される。

{"name":["nameにtarouは指定しないでください!!!"]}
【参考】
Sexy Validationで独自のValidationを - takkan_mのNo planな日常
http://d.hatena.ne.jp/takkan_m/20101008/1286548261

参考

validates - リファレンス - Railsドキュメント
http://railsdoc.com/references/validates