def validate_length(*params)
c = {
:min => nil, :max => nil, :range => nil, :length => nil,
:msg => nil,
:msg_no_value => N::Validation::Errors.no_value,
:msg_short => N::Validation::Errors.too_short,
:msg_long => N::Validation::Errors.too_long,
:on => :save
}
c.update(params.pop) if params.last.is_a?(Hash)
min, max = c[:min], c[:max]
range, length = c[:range], c[:length]
count = 0
[min, max, range, length].each { |o| count += 1 if o }
if count == 0
raise(ArgumentError,
'One of :min, :max, :range, :length must be provided!')
end
if count > 1
raise(ArgumentError,
'The :min, :max, :range, :length options are mutually exclusive!')
end
for name in params
if min
c[:msg] ||= N::Validation::Errors.too_short
code = %{
if obj.#{name}.nil?
errors.add(:#{name}, '#{c[:msg_no_value]}')
elsif obj.#{name}.to_s.length < #{min}
msg = '#{c[:msg]}'
msg = (msg % #{min}) rescue msg
errors.add(:#{name}, msg)
end;
}
elsif max
c[:msg] ||= N::Validation::Errors.too_long
code = %{
if obj.#{name}.nil?
errors.add(:#{name}, '#{c[:msg_no_value]}')
elsif obj.#{name}.to_s.length > #{max}
msg = '#{c[:msg]}'
msg = (msg % #{max}) rescue msg
errors.add(:#{name}, msg)
end;
}
elsif range
code = %{
if obj.#{name}.nil?
errors.add(:#{name}, '#{c[:msg_no_value]}')
elsif obj.#{name}.to_s.length < #{range.first}
msg = '#{c[:msg_short]}'
msg = (msg % #{range.first}) rescue msg
errors.add(:#{name}, msg)
elsif obj.#{name}.to_s.length > #{range.last}
msg = '#{c[:msg_long]}'
msg = (msg % #{range.last}) rescue msg
errors.add(:#{name}, msg)
end;
}
elsif length
c[:msg] ||= N::Validation::Errors.invalid_length
code = %{
if obj.#{name}.nil?
errors.add(:#{name}, '#{c[:msg_no_value]}')
elsif obj.#{name}.to_s.length != #{length}
msg = '#{c[:msg]}'
msg = (msg % #{length}) rescue msg
errors.add(:#{name}, msg)
end;
}
end
__meta[:validations] << [code, c[:on]]
end
end