diff options
Diffstat (limited to 'activemodel/lib/active_model/validations')
14 files changed, 171 insertions, 176 deletions
diff --git a/activemodel/lib/active_model/validations/absence.rb b/activemodel/lib/active_model/validations/absence.rb index 75bf655578..385d9f27e0 100644 --- a/activemodel/lib/active_model/validations/absence.rb +++ b/activemodel/lib/active_model/validations/absence.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActiveModel module Validations # == \Active \Model Absence Validator @@ -22,7 +24,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_absence_of(*attr_names) validates_with AbsenceValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb index a04e5f347e..f35e4dec7f 100644 --- a/activemodel/lib/active_model/validations/acceptance.rb +++ b/activemodel/lib/active_model/validations/acceptance.rb @@ -1,5 +1,6 @@ -module ActiveModel +# frozen_string_literal: true +module ActiveModel module Validations class AcceptanceValidator < EachValidator # :nodoc: def initialize(options) @@ -15,58 +16,60 @@ module ActiveModel private - def setup!(klass) - klass.include(LazilyDefineAttributes.new(AttributeDefinition.new(attributes))) - end + def setup!(klass) + klass.include(LazilyDefineAttributes.new(AttributeDefinition.new(attributes))) + end - def acceptable_option?(value) - Array(options[:accept]).include?(value) - end + def acceptable_option?(value) + Array(options[:accept]).include?(value) + end - class LazilyDefineAttributes < Module - def initialize(attribute_definition) - define_method(:respond_to_missing?) do |method_name, include_private=false| - super(method_name, include_private) || attribute_definition.matches?(method_name) - end + class LazilyDefineAttributes < Module + def initialize(attribute_definition) + define_method(:respond_to_missing?) do |method_name, include_private = false| + super(method_name, include_private) || attribute_definition.matches?(method_name) + end - define_method(:method_missing) do |method_name, *args, &block| - if attribute_definition.matches?(method_name) - attribute_definition.define_on(self.class) - send(method_name, *args, &block) - else - super(method_name, *args, &block) + define_method(:method_missing) do |method_name, *args, &block| + if attribute_definition.matches?(method_name) + attribute_definition.define_on(self.class) + send(method_name, *args, &block) + else + super(method_name, *args, &block) + end end end end - end - class AttributeDefinition - def initialize(attributes) - @attributes = attributes.map(&:to_s) - end + class AttributeDefinition + def initialize(attributes) + @attributes = attributes.map(&:to_s) + end - def matches?(method_name) - attr_name = convert_to_reader_name(method_name) - attributes.include?(attr_name) - end + def matches?(method_name) + attr_name = convert_to_reader_name(method_name) + attributes.include?(attr_name) + end - def define_on(klass) - attr_readers = attributes.reject { |name| klass.attribute_method?(name) } - attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") } - klass.send(:attr_reader, *attr_readers) - klass.send(:attr_writer, *attr_writers) - end + def define_on(klass) + attr_readers = attributes.reject { |name| klass.attribute_method?(name) } + attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") } + klass.send(:attr_reader, *attr_readers) + klass.send(:attr_writer, *attr_writers) + end - protected + # TODO Change this to private once we've dropped Ruby 2.2 support. + # Workaround for Ruby 2.2 "private attribute?" warning. + protected - attr_reader :attributes + attr_reader :attributes - private + private - def convert_to_reader_name(method_name) - method_name.to_s.chomp('=') + def convert_to_reader_name(method_name) + method_name.to_s.chomp("=") + end end - end end module HelperMethods @@ -94,7 +97,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information. + # See <tt>ActiveModel::Validations#validates</tt> for more information. def validates_acceptance_of(*attr_names) validates_with AcceptanceValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index 52111e5442..887d31ae2a 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActiveModel module Validations # == Active \Model \Validation \Callbacks @@ -23,14 +25,12 @@ module ActiveModel included do include ActiveSupport::Callbacks define_callbacks :validation, - terminator: deprecated_false_terminator, skip_after_callbacks_if_terminated: true, scope: [:kind, :name] end module ClassMethods - # Defines a callback that will get called right before validation - # happens. + # Defines a callback that will get called right before validation. # # class Person # include ActiveModel::Validations @@ -54,19 +54,21 @@ module ActiveModel # person.valid? # => true # person.name # => "bob" def before_validation(*args, &block) - options = args.last - if options.is_a?(Hash) && options[:on] - options[:if] = Array(options[:if]) + options = args.extract_options! + + if options.key?(:on) + options = options.dup options[:on] = Array(options[:on]) + options[:if] = Array(options[:if]) options[:if].unshift ->(o) { - options[:on].include? o.validation_context + !(options[:on] & Array(o.validation_context)).empty? } end - set_callback(:validation, :before, *args, &block) + + set_callback(:validation, :before, *args, options, &block) end - # Defines a callback that will get called right after validation - # happens. + # Defines a callback that will get called right after validation. # # class Person # include ActiveModel::Validations @@ -94,22 +96,25 @@ module ActiveModel # person.status # => true def after_validation(*args, &block) options = args.extract_options! + options = options.dup options[:prepend] = true - options[:if] = Array(options[:if]) - if options[:on] + + if options.key?(:on) options[:on] = Array(options[:on]) + options[:if] = Array(options[:if]) options[:if].unshift ->(o) { - options[:on].include? o.validation_context + !(options[:on] & Array(o.validation_context)).empty? } end - set_callback(:validation, :after, *(args << options), &block) + + set_callback(:validation, :after, *args, options, &block) end end - protected + private # Overwrite run validations to include callbacks. - def run_validations! #:nodoc: + def run_validations! _run_validation_callbacks { super } end end diff --git a/activemodel/lib/active_model/validations/clusivity.rb b/activemodel/lib/active_model/validations/clusivity.rb index d49af603bb..0b9b5ce6a1 100644 --- a/activemodel/lib/active_model/validations/clusivity.rb +++ b/activemodel/lib/active_model/validations/clusivity.rb @@ -1,4 +1,6 @@ -require 'active_support/core_ext/range' +# frozen_string_literal: true + +require "active_support/core_ext/range" module ActiveModel module Validations @@ -16,12 +18,12 @@ module ActiveModel def include?(record, value) members = if delimiter.respond_to?(:call) - delimiter.call(record) - elsif delimiter.respond_to?(:to_sym) - record.send(delimiter) - else - delimiter - end + delimiter.call(record) + elsif delimiter.respond_to?(:to_sym) + record.send(delimiter) + else + delimiter + end members.send(inclusion_method(members), value) end diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb index 8f8ade90bb..1b5d5b09ab 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -1,5 +1,6 @@ -module ActiveModel +# frozen_string_literal: true +module ActiveModel module Validations class ConfirmationValidator < EachValidator # :nodoc: def initialize(options) @@ -8,7 +9,7 @@ module ActiveModel end def validate_each(record, attribute, value) - if (confirmed = record.send("#{attribute}_confirmation")) + unless (confirmed = record.send("#{attribute}_confirmation")).nil? unless confirmation_value_equal?(record, attribute, value, confirmed) human_attribute_name = record.class.human_attribute_name(attribute) record.errors.add(:"#{attribute}_confirmation", :confirmation, options.except(:case_sensitive).merge!(attribute: human_attribute_name)) @@ -17,23 +18,23 @@ module ActiveModel end private - def setup!(klass) - klass.send(:attr_reader, *attributes.map do |attribute| - :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation") - end.compact) + def setup!(klass) + klass.send(:attr_reader, *attributes.map do |attribute| + :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation") + end.compact) - klass.send(:attr_writer, *attributes.map do |attribute| - :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=") - end.compact) - end + klass.send(:attr_writer, *attributes.map do |attribute| + :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=") + end.compact) + end - def confirmation_value_equal?(record, attribute, value, confirmed) - if !options[:case_sensitive] && value.is_a?(String) - value.casecmp(confirmed) == 0 - else - value == confirmed + def confirmation_value_equal?(record, attribute, value, confirmed) + if !options[:case_sensitive] && value.is_a?(String) + value.casecmp(confirmed) == 0 + else + value == confirmed + end end - end end module HelperMethods @@ -70,7 +71,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_confirmation_of(*attr_names) validates_with ConfirmationValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb index 6f4276cc2a..3be7ab6ba8 100644 --- a/activemodel/lib/active_model/validations/exclusion.rb +++ b/activemodel/lib/active_model/validations/exclusion.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + require "active_model/validations/clusivity" module ActiveModel - module Validations class ExclusionValidator < EachValidator # :nodoc: include Clusivity @@ -39,7 +40,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_exclusion_of(*attr_names) validates_with ExclusionValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb index 46a2e54fba..7c3f091473 100644 --- a/activemodel/lib/active_model/validations/format.rb +++ b/activemodel/lib/active_model/validations/format.rb @@ -1,5 +1,6 @@ -module ActiveModel +# frozen_string_literal: true +module ActiveModel module Validations class FormatValidator < EachValidator # :nodoc: def validate_each(record, attribute, value) @@ -8,7 +9,7 @@ module ActiveModel record_error(record, attribute, :with, value) if value.to_s !~ regexp elsif options[:without] regexp = option_call(record, :without) - record_error(record, attribute, :without, value) if value.to_s =~ regexp + record_error(record, attribute, :without, value) if regexp.match?(value.to_s) end end @@ -23,33 +24,33 @@ module ActiveModel private - def option_call(record, name) - option = options[name] - option.respond_to?(:call) ? option.call(record) : option - end + def option_call(record, name) + option = options[name] + option.respond_to?(:call) ? option.call(record) : option + end - def record_error(record, attribute, name, value) - record.errors.add(attribute, :invalid, options.except(name).merge!(value: value)) - end + def record_error(record, attribute, name, value) + record.errors.add(attribute, :invalid, options.except(name).merge!(value: value)) + end - def check_options_validity(name) - if option = options[name] - if option.is_a?(Regexp) - if options[:multiline] != true && regexp_using_multiline_anchors?(option) - raise ArgumentError, "The provided regular expression is using multiline anchors (^ or $), " \ - "which may present a security risk. Did you mean to use \\A and \\z, or forgot to add the " \ - ":multiline => true option?" + def check_options_validity(name) + if option = options[name] + if option.is_a?(Regexp) + if options[:multiline] != true && regexp_using_multiline_anchors?(option) + raise ArgumentError, "The provided regular expression is using multiline anchors (^ or $), " \ + "which may present a security risk. Did you mean to use \\A and \\z, or forgot to add the " \ + ":multiline => true option?" + end + elsif !option.respond_to?(:call) + raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}" end - elsif !option.respond_to?(:call) - raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}" end end - end - def regexp_using_multiline_anchors?(regexp) - source = regexp.source - source.start_with?("^") || (source.end_with?("$") && !source.end_with?("\\$")) - end + def regexp_using_multiline_anchors?(regexp) + source = regexp.source + source.start_with?("^") || (source.end_with?("$") && !source.end_with?("\\$")) + end end module HelperMethods @@ -104,7 +105,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_format_of(*attr_names) validates_with FormatValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/helper_methods.rb b/activemodel/lib/active_model/validations/helper_methods.rb index 2176115334..730173f2f9 100644 --- a/activemodel/lib/active_model/validations/helper_methods.rb +++ b/activemodel/lib/active_model/validations/helper_methods.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActiveModel module Validations module HelperMethods # :nodoc: diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb index 03e0ef56d8..3104e7e329 100644 --- a/activemodel/lib/active_model/validations/inclusion.rb +++ b/activemodel/lib/active_model/validations/inclusion.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + require "active_model/validations/clusivity" module ActiveModel - module Validations class InclusionValidator < EachValidator # :nodoc: include Clusivity @@ -37,7 +38,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_inclusion_of(*attr_names) validates_with InclusionValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index 79297ac119..d6c80b2c5d 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -1,4 +1,4 @@ -require "active_support/core_ext/string/strip" +# frozen_string_literal: true module ActiveModel module Validations @@ -6,7 +6,7 @@ module ActiveModel MESSAGES = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze - RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long] + RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :too_short, :too_long] def initialize(options) if range = (options.delete(:in) || options.delete(:within)) @@ -18,27 +18,6 @@ module ActiveModel options[:minimum] = 1 end - if options[:tokenizer] - ActiveSupport::Deprecation.warn(<<-EOS.strip_heredoc) - The `:tokenizer` option is deprecated, and will be removed in Rails 5.1. - You can achieve the same functionality by defining an instance method - with the value that you want to validate the length of. For example, - - validates_length_of :essay, minimum: 100, - tokenizer: ->(str) { str.scan(/\w+/) } - - should be written as - - validates_length_of :words_in_essay, minimum: 100 - - private - - def words_in_essay - essay.scan(/\w+/) - end - EOS - end - super end @@ -46,20 +25,19 @@ module ActiveModel keys = CHECKS.keys & options.keys if keys.empty? - raise ArgumentError, 'Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.' + raise ArgumentError, "Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option." end keys.each do |key| value = options[key] - unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY - raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity" + unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc) + raise ArgumentError, ":#{key} must be a nonnegative Integer, Infinity, Symbol, or Proc" end end end def validate_each(record, attribute, value) - value = tokenize(record, value) value_length = value.respond_to?(:length) ? value.length : value.to_s.length errors_options = options.except(*RESERVED_OPTIONS) @@ -67,6 +45,12 @@ module ActiveModel next unless check_value = options[key] if !value.nil? || skip_nil_check?(key) + case check_value + when Proc + check_value = check_value.call(record) + when Symbol + check_value = record.send(check_value) + end next if value_length.send(validity_check, check_value) end @@ -80,24 +64,12 @@ module ActiveModel end private - def tokenize(record, value) - tokenizer = options[:tokenizer] - if tokenizer && value.kind_of?(String) - if tokenizer.kind_of?(Proc) - tokenizer.call(value) - elsif record.respond_to?(tokenizer) - record.send(tokenizer, value) - end - end || value - end - - def skip_nil_check?(key) - key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil? - end + def skip_nil_check?(key) + key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil? + end end module HelperMethods - # Validates that the specified attributes match the length restrictions # supplied. Only one constraint option can be used at a time apart from # +:minimum+ and +:maximum+ that can be combined together: @@ -146,7 +118,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+ and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_length_of(*attr_names) validates_with LengthValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index ad7012df48..31750ba78e 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -1,5 +1,6 @@ -module ActiveModel +# frozen_string_literal: true +module ActiveModel module Validations class NumericalityValidator < EachValidator # :nodoc: CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=, @@ -27,8 +28,6 @@ module ActiveModel raw_value = value end - return if options[:allow_nil] && raw_value.nil? - unless is_number?(raw_value) record.errors.add(attr_name, :not_a_number, filtered_options(raw_value)) return @@ -39,7 +38,9 @@ module ActiveModel return end - unless raw_value.is_a?(Numeric) + if raw_value.is_a?(Numeric) + value = raw_value + else value = parse_raw_value_as_a_number(raw_value) end @@ -64,7 +65,7 @@ module ActiveModel end end - protected + private def is_number?(raw_value) !parse_raw_value_as_a_number(raw_value).nil? @@ -73,6 +74,7 @@ module ActiveModel end def parse_raw_value_as_a_number(raw_value) + return raw_value.to_i if is_integer?(raw_value) Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/ end @@ -97,8 +99,6 @@ module ActiveModel end end - private - def record_attribute_changed_in_place?(record, attr_name) record.respond_to?(:attribute_changed_in_place?) && record.attribute_changed_in_place?(attr_name.to_s) @@ -108,7 +108,7 @@ module ActiveModel module HelperMethods # Validates whether the value of the specified attribute is numeric by # trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt> - # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\Z/</tt> + # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\z/</tt> # (if <tt>only_integer</tt> is set to +true+). # # class Person < ActiveRecord::Base @@ -120,7 +120,7 @@ module ActiveModel # * <tt>:only_integer</tt> - Specifies whether the value has to be an # integer, e.g. an integral value (default is +false+). # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is - # +false+). Notice that for fixnum and float columns empty strings are + # +false+). Notice that for Integer and Float columns empty strings are # converted to +nil+. # * <tt>:greater_than</tt> - Specifies the value must be greater than the # supplied value. @@ -139,7 +139,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+ . - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information # # The following checks can also be supplied with a proc or a symbol which # corresponds to a method: diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb index 5d593274eb..8787a75afa 100644 --- a/activemodel/lib/active_model/validations/presence.rb +++ b/activemodel/lib/active_model/validations/presence.rb @@ -1,6 +1,6 @@ +# frozen_string_literal: true module ActiveModel - module Validations class PresenceValidator < EachValidator # :nodoc: def validate_each(record, attr_name, value) @@ -30,7 +30,7 @@ module ActiveModel # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. - # See <tt>ActiveModel::Validation#validates</tt> for more information + # See <tt>ActiveModel::Validations#validates</tt> for more information def validates_presence_of(*attr_names) validates_with PresenceValidator, _merge_attributes(attr_names) end diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index 1da4df21e7..e28e7e9219 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -1,4 +1,6 @@ -require 'active_support/core_ext/hash/slice' +# frozen_string_literal: true + +require "active_support/core_ext/hash/slice" module ActiveModel module Validations @@ -18,7 +20,6 @@ module ActiveModel # validates :first_name, length: { maximum: 30 } # validates :age, numericality: true # validates :username, presence: true - # validates :username, uniqueness: true # # The power of the +validates+ method comes when using custom validators # and default validators in one call for a given attribute. @@ -34,7 +35,7 @@ module ActiveModel # include ActiveModel::Validations # attr_accessor :name, :email # - # validates :name, presence: true, uniqueness: true, length: { maximum: 100 } + # validates :name, presence: true, length: { maximum: 100 } # validates :email, presence: true, email: true # end # @@ -72,7 +73,7 @@ module ActiveModel # There is also a list of options that could be used along with validators: # # * <tt>:on</tt> - Specifies the contexts where this validation is active. - # Runs in all validation contexts by default (nil). You can pass a symbol + # Runs in all validation contexts by default +nil+. You can pass a symbol # or an array of symbols. (e.g. <tt>on: :create</tt> or # <tt>on: :custom_validation_context</tt> or # <tt>on: [:create, :custom_validation_context]</tt>) @@ -94,7 +95,7 @@ module ActiveModel # Example: # # validates :password, presence: true, confirmation: true, if: :password_required? - # validates :token, uniqueness: true, strict: TokenGenerationException + # validates :token, length: 24, strict: TokenLengthException # # # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+ @@ -115,7 +116,7 @@ module ActiveModel key = "#{key.to_s.camelize}Validator" begin - validator = key.include?('::'.freeze) ? key.constantize : const_get(key) + validator = key.include?("::".freeze) ? key.constantize : const_get(key) rescue NameError raise ArgumentError, "Unknown validator: '#{key}'" end @@ -148,15 +149,15 @@ module ActiveModel validates(*(attributes << options)) end - protected + private # When creating custom validators, it might be useful to be able to specify # additional default keys. This can be done by overwriting this method. - def _validates_default_keys # :nodoc: - [:if, :unless, :on, :allow_blank, :allow_nil , :strict] + def _validates_default_keys + [:if, :unless, :on, :allow_blank, :allow_nil, :strict] end - def _parse_validates_options(options) # :nodoc: + def _parse_validates_options(options) case options when TrueClass {} diff --git a/activemodel/lib/active_model/validations/with.rb b/activemodel/lib/active_model/validations/with.rb index 6de01b3392..d777ac836e 100644 --- a/activemodel/lib/active_model/validations/with.rb +++ b/activemodel/lib/active_model/validations/with.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true + +require "active_support/core_ext/array/extract_options" + module ActiveModel module Validations class WithValidator < EachValidator # :nodoc: @@ -43,7 +47,7 @@ module ActiveModel # # Configuration options: # * <tt>:on</tt> - Specifies the contexts where this validation is active. - # Runs in all validation contexts by default (nil). You can pass a symbol + # Runs in all validation contexts by default +nil+. You can pass a symbol # or an array of symbols. (e.g. <tt>on: :create</tt> or # <tt>on: :custom_validation_context</tt> or # <tt>on: [:create, :custom_validation_context]</tt>) @@ -59,7 +63,7 @@ module ActiveModel # The method, proc or string should return or evaluate to a +true+ or # +false+ value. # * <tt>:strict</tt> - Specifies whether validation should be strict. - # See <tt>ActiveModel::Validation#validates!</tt> for more information. + # See <tt>ActiveModel::Validations#validates!</tt> for more information. # # If you pass any additional configuration options, they will be passed # to the class and available as +options+: |