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

后端 未结 13 881
情话喂你
情话喂你 2020-12-07 17:08

Rails displays all validation error messages associated with a given field. If I have three validates_XXXXX_of :email, and I leave the field blank, I get three

13条回答
  •  南方客
    南方客 (楼主)
    2020-12-07 17:53

    [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
    

提交回复
热议问题