Rails validation error messages: Displaying only one error message per field

[Update] Jan/2013 to Rails 3.2.x – update syntax; add spec

Inspired by new validation methods in Rails 3.0 I’m adding this tiny Validator. I call it ReduceValidator.

lib/reduce_validator.rb:

# show only one error message per field
#
class ReduceValidator < ActiveModel::EachValidator

  def validate_each(record, attribute, value)
    return until record.errors.messages.has_key?(attribute)
    record.errors[attribute].slice!(-1) until record.errors[attribute].size <= 1
  end
end

My Model looking like – notice the :reduce => true:

validates :title, :presence => true, :inclusion => { :in => %w[ Mr Mrs ] }, :reduce => true
validates :firstname, :presence => true, :length => { :within => 2..50 }, :format => { :without => /^\D{1}[.]/i }, :reduce => true
validates :lastname, :presence => true, :length => { :within => 2..50 }, :format => { :without => /^\D{1}[.]/i }, :reduce => true

Works like a charm in my current Rails Project.
The advantageous is, i’ve put the validator only on a few fields not all.

spec/lib/reduce_validator_spec.rb:

require 'spec_helper'

describe ReduceValidator do

  let(:reduce_validator) { ReduceValidator.new({ :attributes => {} }) }

  let(:item) { mock_model("Item") }
  subject { item }

  before(:each) do
    item.errors.add(:name, "message one")
    item.errors.add(:name, "message two")
  end

  it { should have(2).error_on(:name) }

  it "should reduce error messages" do
    reduce_validator.validate_each(item, :name, '')
    should have(1).error_on(:name)
  end

end

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)