ActiveRecord Validation #3 - validates_with -
公式ドキュメント: http://guides.rubyonrails.org/active_record_validations.html#validates-with
ActiveModel::Validatorを用いて検証処理を実装する方法を提供するヘルパー的な感じなのではと
require "rails_helper"
class EntryValidator < ActiveModel::Validator
def validate(record)
# optionsでバリデーションオプションを取得可能
record.errors[:name] << "can`t be blank" if record.name.blank?
end
end
class Entry < ActiveRecord::Base
validates_with EntryValidator,
fields: [:name] # options
end
describe Entry do
fixtures :entry
it "validates_withのテスト" do
expect(Entry.new({ name: "hoge" }).valid?).to eq true
entry = Entry.new
expect(entry.valid?).to eq false
errors = entry.errors
expect(errors).not_to be_empty
messages = errors.messages
expect(messages).not_to be_empty
message = messages.first
expect(message).to eq [:name, ["can`t be blank"]]
end
end
てな感じっすけど、例えばvalidateメソッド内でpresenceとかを指定して既存するバリデーションで処理したいようなケースの場合には
class EntryValidator < ActiveModel::Validator
def validate(record)
record.validates_presence_of :name
end
end
みたいにするか
class EntryValidator < ActiveModel::Validator
def validate(record)
ActiveModel::Validations::PresenceValidator.new(attributes: [:name]).validate record
end
end
みたいな事すれば良いっぽい。これが良いのかは微妙だけど
又、別にActiveModel::Validatorを実装しなくても単純なRubyオブジェクトでメソッドを実装するだけでも出来る方法もあるっぽい
require "rails_helper"
class EntryValidator
def initialize(entry)
@entry = entry
end
def validate
@entry.errors[:name] << "can`t be blank" if @entry.name.blank?
end
end
class Entry < ActiveRecord::Base
validate do |entry|
EntryValidator.new(entry).validate
end
end
describe Entry do
fixtures :entry
it "validates_withのテスト" do
expect(Entry.new({ name: "hoge" }).valid?).to eq true
entry = Entry.new
expect(entry.valid?).to eq false
errors = entry.errors
expect(errors).not_to be_empty
messages = errors.messages
expect(messages).not_to be_empty
message = messages.first
expect(message).to eq [:name, ["can`t be blank"]]
end
end
っていう感じで。まぁドキュメント読んだ方が良いかと