LoginSignup
16
12

More than 5 years have passed since last update.

Ruby on Railsで独自のValidatorを追加してテストする

Posted at

書いてあること

  • 簡単な Validator の作り方
  • RSpec のテストの書き方

Validator を作る

app/validators に Validator を追加していきます。

今回は Rails 標準の validates_numericality_of の単純に大小比較するだけのやつを作ります。

↓使用イメージとしてはこんな感じで

class Hoge
  validates :value1, greater_than: :value2
end

↓ Validator のコードはこんな感じ

app/validators/greater_than_validator.rb
class GreaterThanValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    return if value > record[options[:with]]
    record.errors[attribute] << (options[:message] || "must be greater than #{options[:with]}")
  end
end 
  • record には検証対象のレコード
  • attribute には検証対象の要素名の Symbol
  • value には検証対象の要素に入っている値

が入ってきます。

それとは別に Validator に指定した要素が諸々 options の中に入ってます。今回の場合は :value2 という Symbol です。他に色々指定した場合は色々入ってくると思うので、そこは色々試してみてください。

テストを書く

spec/validators/greater_than_validator_spec.rb
require 'rails_helper'

describe GreaterThanValidator, type: :validator do
  let(:clazz) do
    Struct.new(:value1, :value2) do
      include ActiveModel::Validations
      validates :value2, greater_than: :value1
    end
  end

  describe '#validate_each' do
    subject { clazz.new(value1, value2) }

    context 'when value1 higher than value2' do
      let(:value1) { 1 }
      let(:value2) { value1 + 99 }
      it { is_expected.to be_valid }
    end

    context 'when value1 lower than value2' do
      let(:value1) { 1 }
      let(:value2) { value1 - 99 }
      it { is_expected.not_to be_valid }
    end

    context 'when value1 equal value2' do
      let(:value1) { 1 }
      let(:value2) { value1 }
      it { is_expected.not_to be_valid }
    end
  end

  describe 'error messages' do
    subject { object.errors.messages }

    let(:object) { clazz.new(100, 0) }
    before { object.validate }

    it { is_expected.to eq(value2: ['must be greater than value1']) }
  end
end

ポイントとしては let(:clazz) の部分で、 Struct.new を使って include ActiveModel::Validations することで検証対象のモデルをテスト用に作れるという感じです。

あとは素朴に be_valid とかやってるだけ。

16
12
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
16
12