Class: ActiveModel::Validations::WordCountValidator

Inherits:
EachValidator
  • Object
show all
Defined in:
lib/active_model/validations/word_count.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ WordCountValidator

Provide option defaults and normalize options. This is done prior to check_validity! as options becomes frozen and check_validity! can only report errors but not modify the options.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/active_model/validations/word_count.rb', line 16

def initialize(options)
  options[:min] = options.delete(:minimum) if options.has_key?(:minimum)
  options[:max] = options.delete(:maximum) if options.has_key?(:maximum)
  options[:max] ||= 100
  options[:min] ||= 0
  options[:strip_tags] = true unless options.has_key?(:strip_tags)
  options[:strip_punctuation] = true unless options.has_key?(:strip_punctuation)
  if options.has_key?(:in)
    range = options[:in]
    if range.present? && range.respond_to?(:min) && range.respond_to?(:max)
      options[:min], options[:max] = range.min, range.max
      options.delete :in
    end
  end
  super
end

Instance Method Details

#base_optionsObject



61
62
63
# File 'lib/active_model/validations/word_count.rb', line 61

def base_options
  options.except(:in, :min, :max, :skip_max, :skip_min)
end

#check_validity!Object

Raises:

  • (ArgumentError)


33
34
35
36
37
# File 'lib/active_model/validations/word_count.rb', line 33

def check_validity!
  raise ArgumentError, "You must provide a valid range for the number of words e.g. 2..100" if options.has_key?(:in)
  raise ArgumentError, "The min value must respond to to_i or call" unless options[:min].respond_to?(:to_i) || options[:min].respond_to?(:call)
  raise ArgumentError, "The max value must respond to to_i or call" unless options[:max].respond_to?(:to_i) || options[:max].respond_to?(:call)
end

#options_for(current, expected) ⇒ Object



65
66
67
# File 'lib/active_model/validations/word_count.rb', line 65

def options_for(current, expected)
  base_options.merge :expected_count => expected, :actual_count => current
end

#validate_each(record, attribute, value) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/active_model/validations/word_count.rb', line 39

def validate_each(record, attribute, value)
  min_words = options[:min].respond_to?(:call) ? options[:min][record, attribute, value] : options[:min].to_i
  max_words = options[:max].respond_to?(:call) ? options[:max][record, attribute, value] : options[:max].to_i
  value = ActionController::Base.helpers.strip_tags(value || '').gsub(/ | /i, ' ') if options[:strip_tags]
  value.gsub! /[.(),;:!?%#\$'"_+=\/-]*/, '' if options[:strip_punctuation]
  count = word_count_for(value)
  if !options[:skip_min] && count < min_words
    record.errors.add attribute, :too_few_words,  options_for(count, min_words)
  elsif !options[:skip_max] && count > max_words
    record.errors.add attribute, :too_many_words, options_for(count, max_words)
  end 
end

#word_count_for(value) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/active_model/validations/word_count.rb', line 52

def word_count_for(value)
  if RUBY_VERSION =~ /1\.[0-8]\.*/
    regexp = /\w+/u
  else
    regexp = /\p{Word}+/
  end
  value.to_s.scan(regexp).size
end