Module | CustomValidations |
In: |
lib/custom_validations.rb
|
検証部品を実装するモジュール。
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
1〜9999年の範囲内の日付かどうかをチェックする。
# 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
1〜9999年と1〜12月の範囲内かどうかをチェックする。
# 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
1〜9999年の範囲内かどうかをチェックする。
# 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
# 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