Forum: Ruby on Rails Custom validations in rails: validates_number_range

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
83c8cca11558f32207645ca270ae8475?d=identicon&s=25 Ye Dingding (Guest)
on 2007-06-24 20:59
(Received via mailing list)
http://sishen.lifegoo.com/?p=42

I don't know whether there exists a builtin validation that can check
the
number range. I think the requirement is normal, but indeed, i can't
find
it.  So i wrote a custome validation: validates_number_range, whose
prototype is validates_length_of. If there already exists one, pls tell
me,
:)

The code is below, welcome to give me any advice on my blog. And also,
more
details information on the blog, :)

module ActiveRecord
  module Validations
    module ClassMethods
      def validates_number_range(*attrs)
        validates_numericality_of attrs.first
        options = {
          :too_big => "is too big (maximum is %d)",
          :too_small => "is too small (minimum is %d)",
          :wrong_number => "is the wrong number (should be %d)"
        }.merge(DEFAULT_VALIDATION_OPTIONS)
        options.update(attrs.pop.symbolize_keys) if
attrs.last.is_a?(Hash)

        # Ensure that one and only one range option is specified.
        range_options = ALL_RANGE_OPTIONS & options.keys
        case range_options.size
          when 0
            raise ArgumentError, 'Range unspecified.  Specify the
:within,
:maximum, :minimum, or :is option.'
          when 1
            # Valid number of options; do nothing.
          else
            raise ArgumentError, 'Too many range options specified.
Choose
only one.'
        end

        # Get range option and value.
        option = range_options.first
        option_value = options[range_options.first]

        case option
        when :within, :in
          raise ArgumentError, ":#{option} must be a Range" unless
option_value.is_a?(Range)

          too_small = options[:too_small] % option_value.begin
          too_big  = options[:too_big]  % option_value.end

          validates_each(attrs, options) do |record, attr, value|
            if value.nil? or value < option_value.begin
              record.errors.add(attr, too_small)
            elsif value > option_value.end
              record.errors.add(attr, too_big)
            end
          end
        when :is, :minimum, :maximum
          raise ArgumentError, ":#{option} must be a nonnegative
Integer"
unless option_value.is_a?(Integer) and option_value >= 0

          # Declare different validations per option.
          validity_checks = { :is => "==", :minimum => ">=", :maximum =>
"<=" }
          message_options = { :is => :wrong_number, :minimum =>
:too_small,
:maximum => :too_big }

          message = (options[:message] ||
options[message_options[option]])
% option_value

          validates_each(attrs, options) do |record, attr, value|
            record.errors.add(attr, message) unless !value.nil? and
value.method(validity_checks[option])[option_value]
          end
        end
      end
    end
  end
end
F04efaee460b2ace5575870a4632287d?d=identicon&s=25 Matt Sir (daicoden)
on 2007-06-24 21:33
If I understood what you are trying to do correctly
validates_length_of :user_name, :within => 6..20, :too_long => "pick a
shorter name", :too_short => "pick a longer name"

from
http://railsmanual.com/module/ActiveRecord::Valida...

Matt

Ye Dingding wrote:
> http://sishen.lifegoo.com/?p=42
>
> I don't know whether there exists a builtin validation that can check
> the
> number range. I think the requirement is normal, but indeed, i can't
> find
> it.  So i wrote a custome validation: validates_number_range, whose
> prototype is validates_length_of. If there already exists one, pls tell
> me,
> :)
>
83c8cca11558f32207645ca270ae8475?d=identicon&s=25 Ye Dingding (Guest)
on 2007-06-24 22:13
(Received via mailing list)
No, that's not i want to do. Sorry, my
blog(http://sishen.lifegoo.com/?p=42)
gives more information, so i gave less information in the mail.

My scenario is that I want to check the uploaded file size, for example,
less than 5M. But what validates_length_of is the size, when is a
fixnum, is
4. So validates_length_of can't be work for me.

Using validates_number_range, now i can code as below:

validates_number_range :file_size,
                         :maximum => 5242880,
                         :message => "you can only upload file less than
5M",
                         :on => :create
83c8cca11558f32207645ca270ae8475?d=identicon&s=25 Ye Dingding (Guest)
on 2007-06-27 11:36
(Received via mailing list)
Today i looked through the validations.rb in rails edge. I'm glad to
find
that validates_numericality_of method already has the support for range
check.

The related options are

   - greater_than
   - greater_than_or_equal_to
   - equal_to
   - less_than
   - less_than_or_equal_to
   - odd
   - even

With these, life are more better, :)
This topic is locked and can not be replied to.