Module | CustomValidations
In: | lib/custom_validations.rb

検証部品を実装するモジュール。

### Methods

validates_earlier_date_of validates_filtered_length_of validates_float_of validates_fractional_length_of validates_fullwidth_of validates_inclusion_chars_of validates_integer_of validates_integral_length_of validates_later_date_of validates_minimum_number_of validates_non_negative_float_of validates_non_negative_integer_of validates_nonzero_of validates_period_of validates_row_of validates_year_month_day_of validates_year_month_of validates_year_of validates_zero_of

### Included Modules

GetText::Rails

### Classes and Modules

Module CustomValidations::SingletonValidateable
Module CustomValidations::Validateable

### Public Instance methods

validates_earlier_date_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 532
    532:   def validates_earlier_date_of(*attr_names)
    533:     configuration = {
    534:       :message => ActiveRecord::Errors.default_error_messages[:earlier_date],
    535:     }
    536:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    537:     date = configuration.delete(:than)
    538:     case date
    539:     when String
    540:       display_date = date.to_display_date
    541:       enum = "" ... display_date
    542:       proc = lambda {|value| enum.include?(value.to_display_date)}
    543:     when Time
    544:       display_date = date.strftime("%Y%m%d").to_display_date
    545:       enum = Time.at(0) ... date
    546:       proc = lambda {|value| enum.include?(value)}
    547:     else
    548:       raise ArgumentError, "Date unspecified. Specify the :than option."
    549:     end
    550:     # logic from validates_inclusion_of
    551:     validates_each(attr_names, configuration) do |record, attr_name, value|
    552:       record.errors.add(attr_name, _(configuration[:message]) % {:date => display_date}) unless proc.call(value)
    553:     end
    554:   end

validates_filtered_length_of(*attrs)

[Source]

         # File lib/custom_validations.rb, line 314
    314:   def validates_filtered_length_of(*attrs)
    315:     options = {
    316:       :too_long     => ActiveRecord::Errors.default_error_messages[:too_long],
    317:       :too_short    => ActiveRecord::Errors.default_error_messages[:too_short],
    318:       :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
    319:     }.merge(::ActiveRecord::Validations::ClassMethods::DEFAULT_VALIDATION_OPTIONS)
    320:     options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
    321:
    322:     ## add filter option
    323:     filter = options[:filter]
    324:     unless filter.respond_to?(:call)
    325:       raise ArgumentError, "Filter unspecified. Specify the :filter option."
    326:     end
    327:
    328:     # Ensure that one and only one range option is specified.
    329:     range_options = ::ActiveRecord::Validations::ClassMethods::ALL_RANGE_OPTIONS & options.keys
    330:     case range_options.size
    331:     when 0
    332:       raise ArgumentError, 'Range unspecified.  Specify the :within, :maximum, :minimum, or :is option.'
    333:     when 1
    334:       # Valid number of options; do nothing.
    335:     else
    336:       raise ArgumentError, 'Too many range options specified.  Choose only one.'
    337:     end
    338:
    339:     # Get range option and value.
    340:     option = range_options.first
    341:     option_value = options[range_options.first]
    342:
    343:     case option
    344:     when :within, :in
    345:       raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
    346:
    347:       too_short = options[:too_short] % option_value.begin
    348:       too_long  = options[:too_long]  % option_value.end
    349:
    350:       validates_each(attrs, options) do |record, attr, value|
    351:         ## change from "value.split(//).size" in validates_length_of
    352:         ## to "filter.call(value)".
    353:         if value.nil? or filter.call(value) < option_value.begin
    354:           record.errors.add(attr, too_short)
    355:         elsif filter.call(value) > option_value.end
    356:           record.errors.add(attr, too_long)
    357:         end
    358:       end
    359:     when :is, :minimum, :maximum
    360:       raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
    361:
    362:       # Declare different validations per option.
    363:       validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
    364:       message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
    365:
    366:       message = (options[:message] || options[message_options[option]]) % option_value
    367:
    368:       validates_each(attrs, options) do |record, attr, value|
    369:         ## change from "value.split(//).size" or "value.size" in validates_length_of
    370:         ## to "filter.call(value)".
    371:         begin
    372:           unless !value.nil? and filter.call(Integer(value)).method(validity_checks[option])[option_value]
    373:             record.errors.add(attr, message)
    374:           end
    375:         rescue ArgumentError
    376:           record.errors.add(attr, message)
    377:         end
    378:       end
    379:     end
    380:   end

validates_float_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 178
    178:   def validates_float_of(*attr_names)
    179:     configuration = {
    180:       :message => ActiveRecord::Errors.default_error_messages[:not_float],
    181:       :allow_nil => false,
    182:       :non_negative => false,
    183:     }
    184:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    185:
    186:     configuration[:with] = configuration[:non_negative] ? /\A\+?[0-9]+\.[0-9]+\z/ : /\A[+-]?[0-9]+\.[0-9]+\z/
    187:     attr_names.push configuration
    188:     validates_format_before_type_cast_of(*attr_names)
    189:   end

validates_fractional_length_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 400
    400:   def validates_fractional_length_of(*attr_names)
    401:     configuration = {
    402:       :too_long     => ActiveRecord::Errors.default_error_messages[:too_long_fractional],
    403:       :too_short    => ActiveRecord::Errors.default_error_messages[:too_short_fractional],
    404:       :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length_fractional],
    405:     }
    406:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    407:     configuration[:filter] = proc do |value|
    408:       if /\.([0-9]*)(?![0-9])/ =~ value.to_s
    409:         $1.length
    410:       else
    411:         0
    412:       end
    413:     end
    414:     attr_names.push configuration
    415:     validates_filtered_length_of(*attr_names)
    416:   end

validates_fullwidth_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 255
    255:   def validates_fullwidth_of(*attr_names)
    256:     configuration = {
    257:       :message => ActiveRecord::Errors.default_error_messages[:not_fullwidth_chars],
    258:       :invalid_sequence_message => ActiveRecord::Errors.default_error_messages[:invalid_sequence],
    259:       :blank_message => ActiveRecord::Errors.default_error_messages[:not_fullwidth_chars],
    260:       :on => :save,
    261:       :allow_nil => false,
    262:     }
    263:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    264:
    265:     unless configuration[:allow_nil]
    266:       # use validates_each instead of validates_presence_of because gettextize
    267:       validates_each(attr_names, configuration) do |record, attr_name, value|
    268:         if value.blank?
    269:           record.errors.add attr_name, _(configuration[:blank_message])
    270:         end
    271:       end
    272:     end
    273:
    274:     validates_each(attr_names, configuration) do |record, attr_name, value|
    275:       begin
    276:         cp932_string = Iconv.conv("cp932", "utf-8", value.to_s)
    277:         scanner, char = StringScanner.new(cp932_string), /./s
    278:         while c = scanner.scan(char)
    279:           if c.length != 2
    280:             record.errors.add attr_name, _(configuration[:message])
    281:             break
    282:           end
    283:         end
    284:       rescue Iconv::IllegalSequence
    285:         record.errors.add attr_name, _(configuration[:invalid_sequence])
    286:       end
    287:     end
    288:   end

validates_inclusion_chars_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 290
    290:   def validates_inclusion_chars_of(*attr_names)
    291:     configuration = {
    292:       :message => ActiveRecord::Errors.default_error_messages[:not_inclusion_chars],
    293:       :on => :save,
    294:       :allow_nil => false,
    295:     }
    296:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    297:
    298:     chars = configuration[:chars]
    299:     raise(ArgumentError, "Characters must be supplied as the :chars option of the configuration hash") if chars.blank?
    300:
    301:     if chars.is_a?(Array)
    302:       chars = chars.join("")
    303:     end
    304:     chars = Regexp.escape(chars)
    305:     configuration[:with] = /\A[#{chars}]+\z/
    306:
    307:     validates_each(attr_names, configuration) do |record, attr_name, value|
    308:       unless record.send("#{attr_name}_before_type_cast").to_s =~ configuration[:with]
    309:         record.errors.add(attr_name, _(configuration[:message]) % {:chars => chars})
    310:       end
    311:     end
    312:   end

validates_integer_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 156
    156:   def validates_integer_of(*attr_names)
    157:     configuration = {
    158:       :message => ActiveRecord::Errors.default_error_messages[:not_integer],
    159:       :allow_nil => false,
    160:       :non_negative => false,
    161:     }
    162:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    163:     configuration[:with] = configuration[:non_negative] ? /\A\+?\d+\z/ : /\A[+-]?\d+\z/
    164:     attr_names.push configuration
    165:     validates_format_before_type_cast_of(*attr_names)
    166:   end

validates_integral_length_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 382
    382:   def validates_integral_length_of(*attr_names)
    383:     configuration = {
    384:       :too_long     => ActiveRecord::Errors.default_error_messages[:too_long_integer],
    385:       :too_short    => ActiveRecord::Errors.default_error_messages[:too_short_integer],
    386:       :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length_integer],
    387:     }
    388:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    389:     configuration[:filter] = proc do |value|
    390:       if /\A[+-]?([0-9]*)(?![0-9])/ =~ value.to_s
    391:         $1.length
    392:       else
    393:         0
    394:       end
    395:     end
    396:     attr_names.push configuration
    397:     validates_filtered_length_of(*attr_names)
    398:   end

validates_later_date_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 508
    508:   def validates_later_date_of(*attr_names)
    509:     configuration = {
    510:       :message => ActiveRecord::Errors.default_error_messages[:later_date],
    511:     }
    512:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    513:     date = configuration.delete(:than)
    514:     case date
    515:     when String
    516:       display_date = date.to_display_date
    517:       enum = "" .. display_date
    518:       proc = lambda {|value| enum.include?(value.to_display_date)}
    519:     when Time
    520:       display_date = date.strftime("%Y%m%d").to_display_date
    521:       enum = Time.at(0) .. date
    522:       proc = lambda {|value| enum.include?(value)}
    523:     else
    524:       raise ArgumentError, "Date unspecified. Specify the :than option."
    525:     end
    526:     # logic from validates_exclusion_of
    527:     validates_each(attr_names, configuration) do |record, attr_name, value|
    528:       record.errors.add(attr_name, _(configuration[:message]) % {:date => display_date}) if proc.call(value)
    529:     end
    530:   end

validates_minimum_number_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 476
    476:   def validates_minimum_number_of(*attr_names)
    477:     configuration = {
    478:       :too_long     => ActiveRecord::Errors.default_error_messages[:too_large],
    479:       :too_short    => ActiveRecord::Errors.default_error_messages[:too_small],
    480:       :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_number],
    481:     }
    482:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    483:     configuration[:filter] = proc {|value| value }
    484:     attr_names.push configuration
    485:     validates_filtered_length_of(*attr_names)
    486:   end

validates_non_negative_float_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 168
    168:   def validates_non_negative_float_of(*attr_names)
    169:     configuration = {
    170:       :message => ActiveRecord::Errors.default_error_messages[:negative_float],
    171:       :non_negative => true,
    172:     }
    173:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    174:     attr_names.push configuration
    175:     validates_float_of(*attr_names)
    176:   end

validates_non_negative_integer_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 146
    146:   def validates_non_negative_integer_of(*attr_names)
    147:     configuration = {
    148:       :message => ActiveRecord::Errors.default_error_messages[:negative_integer],
    149:       :non_negative => true,
    150:     }
    151:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    152:     attr_names.push configuration
    153:     validates_integer_of(*attr_names)
    154:   end

validates_nonzero_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 201
    201:   def validates_nonzero_of(*attr_names)
    202:     configuration = {
    203:       :message => ActiveRecord::Errors.default_error_messages[:nonzero],
    204:     }
    205:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    206:
    207:     validates_each(attr_names, configuration) do |record, attr_name, value|
    208:       unless value.to_f.nonzero?
    209:         record.errors.add(attr_name, configuration[:message])
    210:       end
    211:     end
    212:   end

validates_period_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 488
    488:   def validates_period_of(*attr_names)
    489:     configuration = {
    490:       :message => ActiveRecord::Errors.default_error_messages[:period],
    491:     }
    492:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    493:     if e = configuration.delete(:in)
    494:       enum = (e.first.to_display_date .. e.last.to_display_date)
    495:       proc = lambda {|value| enum.include?(value.to_display_date)}
    496:     elsif min = configuration.delete(:minimum)
    497:       proc = lambda {|value| min.to_display_date <= value.to_display_date}
    498:     elsif max = configuration.delete(:maximum)
    499:       proc = lambda {|value| value.to_display_date <= max.to_display_date}
    500:     else
    501:       raise ArgumentError, "no option of the configuration hash"
    502:     end
    503:     validates_each(attr_names, configuration) do |record, attr_name, value|
    504:       record.errors.add(attr_name, configuration[:message]) unless proc.call(value)
    505:     end
    506:   end

validates_row_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 556
    556:   def validates_row_of(*attr_names)
    557:     configuration = {
    558:       :message => ActiveRecord::Errors.default_error_messages[:row],
    559:     }
    560:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    561:
    562:     model_class_name = configuration[:table].classify
    563:     model_class = model_class_name.constantize
    564:     column_name = configuration[:column]
    565:     find_by = "find_by_#{column_name}"
    566:
    567:     validates_each(attr_names, configuration) do |record, attr_name, value|
    568:       if model_class.__send__(find_by, value, :select => "id").nil?
    569:         message = _(configuration[:message]) % {
    570:           :column => model_class.human_attribute_name(column_name),
    571:           :table => _(model_class_name), # FIXME
    572:         }
    573:         record.errors.add(attr_name, message)
    574:       end
    575:     end
    576:   end

validates_year_month_day_of(*attr_names)

1〜9999年の範囲内の日付かどうかをチェックする。

[Source]

         # File lib/custom_validations.rb, line 454
    454:   def validates_year_month_day_of(*attr_names)
    455:     configuration = {
    456:       :message => ActiveRecord::Errors.default_error_messages[:invalid_year_month_day],
    457:     }
    458:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    459:
    460:     validates_each(attr_names, configuration) do |record, attr_name, value|
    461:       begin
    462:         case value.to_s
    463:         when /\A(\d{4})([\/\-]?)(\d{2})\2(\d{2})\z/, /\A(\d+)([\/\-])(\d+)\2(\d+)\z/
    464:           year = $1.to_i
    465:           raise ArgumentError unless (1..9999).include?(year)
    466:           date = Date.new(year, $3.to_i, $4.to_i)
    467:         else
    468:           record.errors.add attr_name, configuration[:message]
    469:         end
    470:       rescue ArgumentError
    471:         record.errors.add attr_name, configuration[:message]
    472:       end
    473:     end
    474:   end

validates_year_month_of(*attr_names)

1〜9999年と1〜12月の範囲内かどうかをチェックする。

[Source]

         # File lib/custom_validations.rb, line 433
    433:   def validates_year_month_of(*attr_names)
    434:     configuration = {
    435:       :message => ActiveRecord::Errors.default_error_messages[:invalid_year_month],
    436:     }
    437:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    438:
    439:     validates_each(attr_names, configuration) do |record, attr_name, value|
    440:       valid = false
    441:       case value.to_s
    442:       when /\A(\d+)[\/\-](\d+)\z/, /\A(\d{4})(\d{2})\z/
    443:         if (1..9999).include?($1.to_i) && (1..12).include?($2.to_i)
    444:           valid = true
    445:         end
    446:       end
    447:       unless valid
    448:         record.errors.add attr_name, configuration[:message]
    449:       end
    450:     end
    451:   end

validates_year_of(*attr_names)

1〜9999年の範囲内かどうかをチェックする。

[Source]

         # File lib/custom_validations.rb, line 419
    419:   def validates_year_of(*attr_names)
    420:     configuration = {
    421:       :message => ActiveRecord::Errors.default_error_messages[:invalid_year],
    422:     }
    423:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    424:
    425:     validates_each(attr_names, configuration) do |record, attr_name, value|
    426:       unless /\A\d+\z/ =~ value.to_s && (1..9999).include?(value.to_i)
    427:         record.errors.add(attr_name, configuration[:message])
    428:       end
    429:     end
    430:   end

validates_zero_of(*attr_names)

[Source]

         # File lib/custom_validations.rb, line 191
    191:   def validates_zero_of(*attr_names)
    192:     configuration = {
    193:       :message => ActiveRecord::Errors.default_error_messages[:not_zero],
    194:       :with => /\A[+-]?0+(?:.0+)?\z/,
    195:     }
    196:     configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
    197:     attr_names.push configuration
    198:     validates_format_before_type_cast_of(*attr_names)
    199:   end

[Validate]