diff options
Diffstat (limited to 'activemodel/lib/active_model')
47 files changed, 500 insertions, 440 deletions
diff --git a/activemodel/lib/active_model/attribute_assignment.rb b/activemodel/lib/active_model/attribute_assignment.rb index 62014cd1cd..7dad3b6dff 100644 --- a/activemodel/lib/active_model/attribute_assignment.rb +++ b/activemodel/lib/active_model/attribute_assignment.rb @@ -1,4 +1,4 @@ -require 'active_support/core_ext/hash/keys' +require "active_support/core_ext/hash/keys" module ActiveModel module AttributeAssignment @@ -35,18 +35,18 @@ module ActiveModel private - def _assign_attributes(attributes) - attributes.each do |k, v| - _assign_attribute(k, v) + def _assign_attributes(attributes) + attributes.each do |k, v| + _assign_attribute(k, v) + end end - end - def _assign_attribute(k, v) - if respond_to?("#{k}=") - public_send("#{k}=", v) - else - raise UnknownAttributeError.new(self, k) + def _assign_attribute(k, v) + if respond_to?("#{k}=") + public_send("#{k}=", v) + else + raise UnknownAttributeError.new(self, k) + end end - end end end diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index cc6285f932..96709486f3 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -1,5 +1,6 @@ -require 'concurrent/map' -require 'mutex_m' +require "concurrent/map" +require "mutex_m" +require "active_support/core_ext/regexp" module ActiveModel # Raised when an attribute is not defined. @@ -366,7 +367,7 @@ module ActiveModel # using the given `extra` args. This falls back on `define_method` # and `send` if the given names cannot be compiled. def define_proxy_call(include_private, mod, name, send, *extra) #:nodoc: - defn = if name =~ NAME_COMPILABLE_REGEXP + defn = if NAME_COMPILABLE_REGEXP.match?(name) "def #{name}(*args)" else "define_method(:'#{name}') do |*args|" @@ -374,7 +375,7 @@ module ActiveModel extra = (extra.map!(&:inspect) << "*args").join(", ".freeze) - target = if send =~ CALL_COMPILABLE_REGEXP + target = if CALL_COMPILABLE_REGEXP.match?(send) "#{"self." unless include_private}#{send}(#{extra})" else "send(:'#{send}', #{extra})" @@ -393,7 +394,7 @@ module ActiveModel AttributeMethodMatch = Struct.new(:target, :attr_name, :method_name) def initialize(options = {}) - @prefix, @suffix = options.fetch(:prefix, ''), options.fetch(:suffix, '') + @prefix, @suffix = options.fetch(:prefix, ""), options.fetch(:suffix, "") @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/ @method_missing_target = "#{@prefix}attribute#{@suffix}" @method_name = "#{prefix}%s#{suffix}" diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb index 0d6a3dc52d..283090e380 100644 --- a/activemodel/lib/active_model/callbacks.rb +++ b/activemodel/lib/active_model/callbacks.rb @@ -1,4 +1,4 @@ -require 'active_support/core_ext/array/extract_options' +require "active_support/core_ext/array/extract_options" module ActiveModel # == Active \Model \Callbacks @@ -122,28 +122,28 @@ module ActiveModel private - def _define_before_model_callback(klass, callback) #:nodoc: - klass.define_singleton_method("before_#{callback}") do |*args, &block| - set_callback(:"#{callback}", :before, *args, &block) + def _define_before_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("before_#{callback}") do |*args, &block| + set_callback(:"#{callback}", :before, *args, &block) + end end - end - def _define_around_model_callback(klass, callback) #:nodoc: - klass.define_singleton_method("around_#{callback}") do |*args, &block| - set_callback(:"#{callback}", :around, *args, &block) + def _define_around_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("around_#{callback}") do |*args, &block| + set_callback(:"#{callback}", :around, *args, &block) + end end - end - def _define_after_model_callback(klass, callback) #:nodoc: - klass.define_singleton_method("after_#{callback}") do |*args, &block| - options = args.extract_options! - options[:prepend] = true - conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v| - v != false - } - options[:if] = Array(options[:if]) << conditional - set_callback(:"#{callback}", :after, *(args << options), &block) + def _define_after_model_callback(klass, callback) #:nodoc: + klass.define_singleton_method("after_#{callback}") do |*args, &block| + options = args.extract_options! + options[:prepend] = true + conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v| + v != false + } + options[:if] = Array(options[:if]) << conditional + set_callback(:"#{callback}", :after, *(args << options), &block) + end end - end end end diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb index a932ada45c..12687c70d3 100644 --- a/activemodel/lib/active_model/conversion.rb +++ b/activemodel/lib/active_model/conversion.rb @@ -46,9 +46,13 @@ module ActiveModel # class Person # include ActiveModel::Conversion # attr_accessor :id + # + # def initialize(id) + # @id = id + # end # end # - # person = Person.create(id: 1) + # person = Person.new(1) # person.to_key # => [1] def to_key key = respond_to?(:id) && id @@ -61,15 +65,20 @@ module ActiveModel # class Person # include ActiveModel::Conversion # attr_accessor :id + # + # def initialize(id) + # @id = id + # end + # # def persisted? # true # end # end # - # person = Person.create(id: 1) + # person = Person.new(1) # person.to_param # => "1" def to_param - (persisted? && key = to_key) ? key.join('-') : nil + (persisted? && key = to_key) ? key.join("-") : nil end # Returns a +string+ identifying the path associated with the object. diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 90047c3c12..6e0af99ad7 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -1,5 +1,5 @@ -require 'active_support/hash_with_indifferent_access' -require 'active_support/core_ext/object/duplicable' +require "active_support/hash_with_indifferent_access" +require "active_support/core_ext/object/duplicable" module ActiveModel # == Active \Model \Dirty @@ -26,8 +26,8 @@ module ActiveModel # # define_attribute_methods :name # - # def initialize(name) - # @name = name + # def initialize + # @name = nil # end # # def name @@ -58,7 +58,7 @@ module ActiveModel # # A newly instantiated +Person+ object is unchanged: # - # person = Person.new("Uncle Bob") + # person = Person.new # person.changed? # => false # # Change the name: @@ -66,11 +66,11 @@ module ActiveModel # person.name = 'Bob' # person.changed? # => true # person.name_changed? # => true - # person.name_changed?(from: "Uncle Bob", to: "Bob") # => true - # person.name_was # => "Uncle Bob" - # person.name_change # => ["Uncle Bob", "Bob"] + # person.name_changed?(from: nil, to: "Bob") # => true + # person.name_was # => nil + # person.name_change # => [nil, "Bob"] # person.name = 'Bill' - # person.name_change # => ["Uncle Bob", "Bill"] + # person.name_change # => [nil, "Bill"] # # Save the changes: # @@ -80,9 +80,9 @@ module ActiveModel # # Reset the changes: # - # person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]} + # person.previous_changes # => {"name" => [nil, "Bill"]} # person.name_previously_changed? # => true - # person.name_previous_change # => ["Uncle Bob", "Bill"] + # person.name_previous_change # => [nil, "Bill"] # person.reload! # person.previous_changes # => {} # @@ -123,9 +123,9 @@ module ActiveModel private_constant :OPTION_NOT_GIVEN included do - attribute_method_suffix '_changed?', '_change', '_will_change!', '_was' - attribute_method_suffix '_previously_changed?', '_previous_change' - attribute_method_affix prefix: 'restore_', suffix: '!' + attribute_method_suffix "_changed?", "_change", "_will_change!", "_was" + attribute_method_suffix "_previously_changed?", "_previous_change" + attribute_method_affix prefix: "restore_", suffix: "!" end # Returns +true+ if any of the attributes have unsaved changes, +false+ otherwise. diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 685e235730..72746e194e 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -1,7 +1,7 @@ -require 'active_support/core_ext/array/conversions' -require 'active_support/core_ext/string/inflections' -require 'active_support/core_ext/object/deep_dup' -require 'active_support/core_ext/string/filters' +require "active_support/core_ext/array/conversions" +require "active_support/core_ext/string/inflections" +require "active_support/core_ext/object/deep_dup" +require "active_support/core_ext/string/filters" module ActiveModel # == Active \Model \Errors @@ -71,8 +71,8 @@ module ActiveModel # end def initialize(base) @base = base - @messages = Hash.new { |messages, attribute| messages[attribute] = [] } - @details = Hash.new { |details, attribute| details[attribute] = [] } + @messages = apply_default_array({}) + @details = apply_default_array({}) end def initialize_dup(other) # :nodoc: @@ -147,9 +147,9 @@ module ActiveModel # Delete messages for +key+. Returns the deleted messages. # - # person.errors[:name] # => ["cannot be nil"] + # person.errors[:name] # => ["cannot be nil"] # person.errors.delete(:name) # => ["cannot be nil"] - # person.errors[:name] # => [] + # person.errors[:name] # => [] def delete(key) details.delete(key) messages.delete(key) @@ -276,11 +276,11 @@ module ActiveModel # person.errors.to_hash(true) # => {:name=>["name cannot be nil"]} def to_hash(full_messages = false) if full_messages - self.messages.each_with_object({}) do |(attribute, array), messages| + messages.each_with_object({}) do |(attribute, array), messages| messages[attribute] = array.map { |message| full_message(attribute, message) } end else - self.messages.dup + without_default_proc(messages) end end @@ -310,9 +310,9 @@ module ActiveModel # <tt>:strict</tt> option can also be set to any other exception. # # person.errors.add(:name, :invalid, strict: true) - # # => ActiveModel::StrictValidationFailed: name is invalid + # # => ActiveModel::StrictValidationFailed: Name is invalid # person.errors.add(:name, :invalid, strict: NameIsInvalid) - # # => NameIsInvalid: name is invalid + # # => NameIsInvalid: Name is invalid # # person.errors.messages # => {} # @@ -372,7 +372,7 @@ module ActiveModel To achieve the same use: - errors.add(attribute, :empty, options) if value.blank? + errors.add(attribute, :blank, options) if value.blank? MESSAGE Array(attributes).each do |attribute| @@ -382,10 +382,21 @@ module ActiveModel end # Returns +true+ if an error on the attribute with the given message is - # present, +false+ otherwise. +message+ is treated the same as for +add+. + # present, or +false+ otherwise. +message+ is treated the same as for +add+. # # person.errors.add :name, :blank - # person.errors.added? :name, :blank # => true + # person.errors.added? :name, :blank # => true + # person.errors.added? :name, "can't be blank" # => true + # + # If the error message requires an option, then it returns +true+ with + # the correct option, or +false+ with an incorrect or missing option. + # + # person.errors.add :name, :too_long, { count: 25 } + # person.errors.added? :name, :too_long, count: 25 # => true + # person.errors.added? :name, "is too long (maximum is 25 characters)" # => true + # person.errors.added? :name, :too_long, count: 24 # => false + # person.errors.added? :name, :too_long # => false + # person.errors.added? :name, "is too long" # => false def added?(attribute, message = :invalid, options = {}) message = message.call if message.respond_to?(:call) message = normalize_message(attribute, message, options) @@ -426,13 +437,12 @@ module ActiveModel # person.errors.full_message(:name, 'is invalid') # => "Name is invalid" def full_message(attribute, message) return message if attribute == :base - attr_name = attribute.to_s.tr('.', '_').humanize + attr_name = attribute.to_s.tr(".", "_").humanize attr_name = @base.class.human_attribute_name(attribute, default: attr_name) - I18n.t(:"errors.format", { + I18n.t(:"errors.format", default: "%{attribute} %{message}", attribute: attr_name, - message: message - }) + message: message) end # Translates an error message in its default scope @@ -493,6 +503,16 @@ module ActiveModel I18n.translate(key, options) end + def marshal_dump + [@base, without_default_proc(@messages), without_default_proc(@details)] + end + + def marshal_load(array) + @base, @messages, @details = array + apply_default_array(@messages) + apply_default_array(@details) + end + private def normalize_message(attribute, message, options) case message @@ -506,6 +526,17 @@ module ActiveModel def normalize_detail(message, options) { error: message }.merge(options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS)) end + + def without_default_proc(hash) + hash.dup.tap do |new_h| + new_h.default_proc = nil + end + end + + def apply_default_array(hash) + hash.default_proc = proc { |h, key| h[key] = [] } + hash + end end # Raised when a validation cannot be corrected by end users and are considered @@ -531,6 +562,15 @@ module ActiveModel end # Raised when unknown attributes are supplied via mass assignment. + # + # class Person + # include ActiveModel::AttributeAssignment + # include ActiveModel::Validations + # end + # + # person = Person.new + # person.assign_attributes(name: 'Gorby') + # # => ActiveModel::UnknownAttributeError: unknown attribute 'name' for Person. class UnknownAttributeError < NoMethodError attr_reader :record, :attribute diff --git a/activemodel/lib/active_model/lint.rb b/activemodel/lib/active_model/lint.rb index 010eaeb170..291a545528 100644 --- a/activemodel/lib/active_model/lint.rb +++ b/activemodel/lib/active_model/lint.rb @@ -20,7 +20,6 @@ module ActiveModel # to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return # +self+. module Tests - # Passes if the object's model responds to <tt>to_key</tt> and if calling # this method returns +nil+ when the object is not persisted. # Fails otherwise. diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb index dac8d549a7..f5765c0c54 100644 --- a/activemodel/lib/active_model/model.rb +++ b/activemodel/lib/active_model/model.rb @@ -1,5 +1,4 @@ module ActiveModel - # == Active \Model \Basic \Model # # Includes the required interface for an object to interact with diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index d86ef6224e..3830d1486d 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -1,7 +1,7 @@ -require 'active_support/core_ext/hash/except' -require 'active_support/core_ext/module/introspection' -require 'active_support/core_ext/module/remove_method' -require 'active_support/core_ext/module/delegation' +require "active_support/core_ext/hash/except" +require "active_support/core_ext/module/introspection" +require "active_support/core_ext/module/remove_method" +require "active_support/core_ext/module/delegation" module ActiveModel class Name @@ -149,7 +149,7 @@ module ActiveModel raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank? - @unnamespaced = @name.sub(/^#{namespace.name}::/, '') if namespace + @unnamespaced = @name.sub(/^#{namespace.name}::/, "") if namespace @klass = klass @singular = _singularize(@name) @plural = ActiveSupport::Inflector.pluralize(@singular) @@ -191,9 +191,9 @@ module ActiveModel private - def _singularize(string) - ActiveSupport::Inflector.underscore(string).tr('/'.freeze, '_'.freeze) - end + def _singularize(string) + ActiveSupport::Inflector.underscore(string).tr("/".freeze, "_".freeze) + end end # == Active \Model \Naming diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index 89da74efa8..1c0fe92bc0 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -55,7 +55,7 @@ module ActiveModel # This is to avoid ActiveModel (and by extension the entire framework) # being dependent on a binary library. begin - require 'bcrypt' + require "bcrypt" rescue LoadError $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install" raise diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index 70e10fa06d..77834f26fc 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -1,5 +1,5 @@ -require 'active_support/core_ext/hash/except' -require 'active_support/core_ext/hash/slice' +require "active_support/core_ext/hash/except" +require "active_support/core_ext/hash/slice" module ActiveModel # == Active \Model \Serialization diff --git a/activemodel/lib/active_model/serializers/json.rb b/activemodel/lib/active_model/serializers/json.rb index b64a8299e6..b5e030a59b 100644 --- a/activemodel/lib/active_model/serializers/json.rb +++ b/activemodel/lib/active_model/serializers/json.rb @@ -1,4 +1,4 @@ -require 'active_support/json' +require "active_support/json" module ActiveModel module Serializers diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb index 8470915abb..b8cf43cc10 100644 --- a/activemodel/lib/active_model/translation.rb +++ b/activemodel/lib/active_model/translation.rb @@ -1,5 +1,4 @@ module ActiveModel - # == Active \Model \Translation # # Provides integration between your object and the Rails internationalization @@ -31,7 +30,7 @@ module ActiveModel # ActiveModel::Errors#full_messages and # ActiveModel::Translation#human_attribute_name. def lookup_ancestors - self.ancestors.select { |x| x.respond_to?(:model_name) } + ancestors.select { |x| x.respond_to?(:model_name) } end # Transforms attribute names into a more human format, such as "First name" diff --git a/activemodel/lib/active_model/type.rb b/activemodel/lib/active_model/type.rb index 6ec3452478..313f17830f 100644 --- a/activemodel/lib/active_model/type.rb +++ b/activemodel/lib/active_model/type.rb @@ -1,22 +1,22 @@ -require 'active_model/type/helpers' -require 'active_model/type/value' +require "active_model/type/helpers" +require "active_model/type/value" -require 'active_model/type/big_integer' -require 'active_model/type/binary' -require 'active_model/type/boolean' -require 'active_model/type/date' -require 'active_model/type/date_time' -require 'active_model/type/decimal' -require 'active_model/type/decimal_without_scale' -require 'active_model/type/float' -require 'active_model/type/immutable_string' -require 'active_model/type/integer' -require 'active_model/type/string' -require 'active_model/type/text' -require 'active_model/type/time' -require 'active_model/type/unsigned_integer' +require "active_model/type/big_integer" +require "active_model/type/binary" +require "active_model/type/boolean" +require "active_model/type/date" +require "active_model/type/date_time" +require "active_model/type/decimal" +require "active_model/type/decimal_without_scale" +require "active_model/type/float" +require "active_model/type/immutable_string" +require "active_model/type/integer" +require "active_model/type/string" +require "active_model/type/text" +require "active_model/type/time" +require "active_model/type/unsigned_integer" -require 'active_model/type/registry' +require "active_model/type/registry" module ActiveModel module Type diff --git a/activemodel/lib/active_model/type/big_integer.rb b/activemodel/lib/active_model/type/big_integer.rb index 4168cbfce7..3b629682fe 100644 --- a/activemodel/lib/active_model/type/big_integer.rb +++ b/activemodel/lib/active_model/type/big_integer.rb @@ -1,13 +1,13 @@ -require 'active_model/type/integer' +require "active_model/type/integer" module ActiveModel module Type class BigInteger < Integer # :nodoc: private - def max_value - ::Float::INFINITY - end + def max_value + ::Float::INFINITY + end end end end diff --git a/activemodel/lib/active_model/type/binary.rb b/activemodel/lib/active_model/type/binary.rb index a0cc45b4c3..819e4e4a96 100644 --- a/activemodel/lib/active_model/type/binary.rb +++ b/activemodel/lib/active_model/type/binary.rb @@ -38,7 +38,7 @@ module ActiveModel alias_method :to_str, :to_s def hex - @value.unpack('H*')[0] + @value.unpack("H*")[0] end def ==(other) diff --git a/activemodel/lib/active_model/type/boolean.rb b/activemodel/lib/active_model/type/boolean.rb index c1bce98c87..f2a47370a3 100644 --- a/activemodel/lib/active_model/type/boolean.rb +++ b/activemodel/lib/active_model/type/boolean.rb @@ -1,21 +1,32 @@ module ActiveModel module Type - class Boolean < Value # :nodoc: - FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set + # == Active \Model \Type \Boolean + # + # A class that behaves like a boolean type, including rules for coercion of user input. + # + # === Coercion + # Values set from user input will first be coerced into the appropriate ruby type. + # Coercion behavior is roughly mapped to Ruby's boolean semantics. + # + # - "false", "f" , "0", +0+ or any other value in +FALSE_VALUES+ will be coerced to +false+ + # - Empty strings are coerced to +nil+ + # - All other values will be coerced to +true+ + class Boolean < Value + FALSE_VALUES = [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"].to_set - def type + def type # :nodoc: :boolean end private - def cast_value(value) - if value == '' - nil - else - !FALSE_VALUES.include?(value) + def cast_value(value) + if value == "" + nil + else + !FALSE_VALUES.include?(value) + end end - end end end end diff --git a/activemodel/lib/active_model/type/date.rb b/activemodel/lib/active_model/type/date.rb index f74243a22c..6e313fbca8 100644 --- a/activemodel/lib/active_model/type/date.rb +++ b/activemodel/lib/active_model/type/date.rb @@ -7,44 +7,48 @@ module ActiveModel :date end + def serialize(value) + cast(value) + end + def type_cast_for_schema(value) "'#{value.to_s(:db)}'" end private - def cast_value(value) - if value.is_a?(::String) - return if value.empty? - fast_string_to_date(value) || fallback_string_to_date(value) - elsif value.respond_to?(:to_date) - value.to_date - else - value + def cast_value(value) + if value.is_a?(::String) + return if value.empty? + fast_string_to_date(value) || fallback_string_to_date(value) + elsif value.respond_to?(:to_date) + value.to_date + else + value + end end - end - ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/ - def fast_string_to_date(string) - if string =~ ISO_DATE - new_date $1.to_i, $2.to_i, $3.to_i + ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/ + def fast_string_to_date(string) + if string =~ ISO_DATE + new_date $1.to_i, $2.to_i, $3.to_i + end end - end - def fallback_string_to_date(string) - new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday)) - end + def fallback_string_to_date(string) + new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday)) + end - def new_date(year, mon, mday) - if year && year != 0 - ::Date.new(year, mon, mday) rescue nil + def new_date(year, mon, mday) + if year && year != 0 + ::Date.new(year, mon, mday) rescue nil + end end - end - def value_from_multiparameter_assignment(*) - time = super - time && time.to_date - end + def value_from_multiparameter_assignment(*) + time = super + time && time.to_date + end end end end diff --git a/activemodel/lib/active_model/type/date_time.rb b/activemodel/lib/active_model/type/date_time.rb index 2f2df4320f..5cb0077e45 100644 --- a/activemodel/lib/active_model/type/date_time.rb +++ b/activemodel/lib/active_model/type/date_time.rb @@ -12,33 +12,33 @@ module ActiveModel private - def cast_value(value) - return apply_seconds_precision(value) unless value.is_a?(::String) - return if value.empty? + def cast_value(value) + return apply_seconds_precision(value) unless value.is_a?(::String) + return if value.empty? - fast_string_to_time(value) || fallback_string_to_time(value) - end + fast_string_to_time(value) || fallback_string_to_time(value) + end - # '0.123456' -> 123456 - # '1.123456' -> 123456 - def microseconds(time) - time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0 - end + # '0.123456' -> 123456 + # '1.123456' -> 123456 + def microseconds(time) + time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0 + end - def fallback_string_to_time(string) - time_hash = ::Date._parse(string) - time_hash[:sec_fraction] = microseconds(time_hash) + def fallback_string_to_time(string) + time_hash = ::Date._parse(string) + time_hash[:sec_fraction] = microseconds(time_hash) - new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)) - end + new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)) + end - def value_from_multiparameter_assignment(values_hash) - missing_parameter = (1..3).detect { |key| !values_hash.key?(key) } - if missing_parameter - raise ArgumentError, missing_parameter + def value_from_multiparameter_assignment(values_hash) + missing_parameter = (1..3).detect { |key| !values_hash.key?(key) } + if missing_parameter + raise ArgumentError, missing_parameter + end + super end - super - end end end end diff --git a/activemodel/lib/active_model/type/decimal.rb b/activemodel/lib/active_model/type/decimal.rb index 11ea327026..6c5c0451c6 100644 --- a/activemodel/lib/active_model/type/decimal.rb +++ b/activemodel/lib/active_model/type/decimal.rb @@ -15,46 +15,47 @@ module ActiveModel private - def cast_value(value) - casted_value = case value - when ::Float - convert_float_to_big_decimal(value) - when ::Numeric, ::String - BigDecimal(value, precision.to_i) - else - if value.respond_to?(:to_d) - value.to_d + def cast_value(value) + casted_value = \ + case value + when ::Float + convert_float_to_big_decimal(value) + when ::Numeric, ::String + BigDecimal(value, precision.to_i) + else + if value.respond_to?(:to_d) + value.to_d + else + cast_value(value.to_s) + end + end + + apply_scale(casted_value) + end + + def convert_float_to_big_decimal(value) + if precision + BigDecimal(apply_scale(value), float_precision) else - cast_value(value.to_s) + value.to_d end end - apply_scale(casted_value) - end - - def convert_float_to_big_decimal(value) - if precision - BigDecimal(apply_scale(value), float_precision) - else - value.to_d - end - end - - def float_precision - if precision.to_i > ::Float::DIG + 1 - ::Float::DIG + 1 - else - precision.to_i + def float_precision + if precision.to_i > ::Float::DIG + 1 + ::Float::DIG + 1 + else + precision.to_i + end end - end - def apply_scale(value) - if scale - value.round(scale) - else - value + def apply_scale(value) + if scale + value.round(scale) + else + value + end end - end end end end diff --git a/activemodel/lib/active_model/type/decimal_without_scale.rb b/activemodel/lib/active_model/type/decimal_without_scale.rb index 129baa0c10..985e1038ed 100644 --- a/activemodel/lib/active_model/type/decimal_without_scale.rb +++ b/activemodel/lib/active_model/type/decimal_without_scale.rb @@ -1,4 +1,4 @@ -require 'active_model/type/big_integer' +require "active_model/type/big_integer" module ActiveModel module Type diff --git a/activemodel/lib/active_model/type/float.rb b/activemodel/lib/active_model/type/float.rb index 0f925bc7e1..4d0d2771a0 100644 --- a/activemodel/lib/active_model/type/float.rb +++ b/activemodel/lib/active_model/type/float.rb @@ -7,19 +7,28 @@ module ActiveModel :float end + def type_cast_for_schema(value) + return "::Float::NAN" if value.try(:nan?) + case value + when ::Float::INFINITY then "::Float::INFINITY" + when -::Float::INFINITY then "-::Float::INFINITY" + else super + end + end + alias serialize cast private - def cast_value(value) - case value - when ::Float then value - when "Infinity" then ::Float::INFINITY - when "-Infinity" then -::Float::INFINITY - when "NaN" then ::Float::NAN - else value.to_f + def cast_value(value) + case value + when ::Float then value + when "Infinity" then ::Float::INFINITY + when "-Infinity" then -::Float::INFINITY + when "NaN" then ::Float::NAN + else value.to_f + end end - end end end end diff --git a/activemodel/lib/active_model/type/helpers.rb b/activemodel/lib/active_model/type/helpers.rb index a805a359ab..82cd9ebe98 100644 --- a/activemodel/lib/active_model/type/helpers.rb +++ b/activemodel/lib/active_model/type/helpers.rb @@ -1,4 +1,4 @@ -require 'active_model/type/helpers/accepts_multiparameter_time' -require 'active_model/type/helpers/numeric' -require 'active_model/type/helpers/mutable' -require 'active_model/type/helpers/time_value' +require "active_model/type/helpers/accepts_multiparameter_time" +require "active_model/type/helpers/numeric" +require "active_model/type/helpers/mutable" +require "active_model/type/helpers/time_value" diff --git a/activemodel/lib/active_model/type/helpers/numeric.rb b/activemodel/lib/active_model/type/helpers/numeric.rb index c883010506..98533f8771 100644 --- a/activemodel/lib/active_model/type/helpers/numeric.rb +++ b/activemodel/lib/active_model/type/helpers/numeric.rb @@ -3,12 +3,13 @@ module ActiveModel module Helpers module Numeric # :nodoc: def cast(value) - value = case value - when true then 1 - when false then 0 - when ::String then value.presence - else value - end + value = \ + case value + when true then 1 + when false then 0 + when ::String then value.presence + else value + end super(value) end @@ -18,16 +19,16 @@ module ActiveModel private - def number_to_non_number?(old_value, new_value_before_type_cast) - old_value != nil && non_numeric_string?(new_value_before_type_cast) - end + def number_to_non_number?(old_value, new_value_before_type_cast) + old_value != nil && non_numeric_string?(new_value_before_type_cast) + end - def non_numeric_string?(value) - # 'wibble'.to_i will give zero, we want to make sure - # that we aren't marking int zero to string zero as - # changed. - value.to_s !~ /\A-?\d+\.?\d*\z/ - end + def non_numeric_string?(value) + # 'wibble'.to_i will give zero, we want to make sure + # that we aren't marking int zero to string zero as + # changed. + value.to_s !~ /\A-?\d+\.?\d*\z/ + end end end end diff --git a/activemodel/lib/active_model/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb index 63993c0d93..d8c5d929a3 100644 --- a/activemodel/lib/active_model/type/helpers/time_value.rb +++ b/activemodel/lib/active_model/type/helpers/time_value.rb @@ -19,7 +19,7 @@ module ActiveModel end def is_utc? - ::Time.zone_default.nil? || ::Time.zone_default =~ 'UTC' + ::Time.zone_default.nil? || ::Time.zone_default =~ "UTC" end def default_timezone @@ -47,30 +47,30 @@ module ActiveModel private - def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil) - # Treat 0000-00-00 00:00:00 as nil. - return if year.nil? || (year == 0 && mon == 0 && mday == 0) + def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil) + # Treat 0000-00-00 00:00:00 as nil. + return if year.nil? || (year == 0 && mon == 0 && mday == 0) - if offset - time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil - return unless time + if offset + time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil + return unless time - time -= offset - is_utc? ? time : time.getlocal - else - ::Time.public_send(default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil + time -= offset + is_utc? ? time : time.getlocal + else + ::Time.public_send(default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil + end end - end - ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/ + ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/ - # Doesn't handle time zones. - def fast_string_to_time(string) - if string =~ ISO_DATETIME - microsec = ($7.to_r * 1_000_000).to_i - new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec + # Doesn't handle time zones. + def fast_string_to_time(string) + if string =~ ISO_DATETIME + microsec = ($7.to_r * 1_000_000).to_i + new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec + end end - end end end end diff --git a/activemodel/lib/active_model/type/immutable_string.rb b/activemodel/lib/active_model/type/immutable_string.rb index 20b8ca0cc4..58268540e5 100644 --- a/activemodel/lib/active_model/type/immutable_string.rb +++ b/activemodel/lib/active_model/type/immutable_string.rb @@ -16,14 +16,15 @@ module ActiveModel private - def cast_value(value) - result = case value - when true then "t" - when false then "f" - else value.to_s - end - result.freeze - end + def cast_value(value) + result = \ + case value + when true then "t" + when false then "f" + else value.to_s + end + result.freeze + end end end end diff --git a/activemodel/lib/active_model/type/integer.rb b/activemodel/lib/active_model/type/integer.rb index eea2280b22..41dd655a5c 100644 --- a/activemodel/lib/active_model/type/integer.rb +++ b/activemodel/lib/active_model/type/integer.rb @@ -31,36 +31,36 @@ module ActiveModel protected - attr_reader :range + attr_reader :range private - def cast_value(value) - case value - when true then 1 - when false then 0 - else - value.to_i rescue nil + def cast_value(value) + case value + when true then 1 + when false then 0 + else + value.to_i rescue nil + end end - end - def ensure_in_range(value) - unless range.cover?(value) - raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit}" + def ensure_in_range(value) + unless range.cover?(value) + raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit}" + end end - end - def max_value - 1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign - end + def max_value + 1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign + end - def min_value - -max_value - end + def min_value + -max_value + end - def _limit - self.limit || DEFAULT_LIMIT - end + def _limit + limit || DEFAULT_LIMIT + end end end end diff --git a/activemodel/lib/active_model/type/registry.rb b/activemodel/lib/active_model/type/registry.rb index adc88eb624..d25f1a129e 100644 --- a/activemodel/lib/active_model/type/registry.rb +++ b/activemodel/lib/active_model/type/registry.rb @@ -23,17 +23,17 @@ module ActiveModel protected - attr_reader :registrations + attr_reader :registrations private - def registration_klass - Registration - end + def registration_klass + Registration + end - def find_registration(symbol, *args) - registrations.find { |r| r.matches?(symbol, *args) } - end + def find_registration(symbol, *args) + registrations.find { |r| r.matches?(symbol, *args) } + end end class Registration @@ -57,7 +57,7 @@ module ActiveModel protected - attr_reader :name, :block + attr_reader :name, :block end end # :startdoc: diff --git a/activemodel/lib/active_model/type/string.rb b/activemodel/lib/active_model/type/string.rb index 8a91410998..c7e0208a5a 100644 --- a/activemodel/lib/active_model/type/string.rb +++ b/activemodel/lib/active_model/type/string.rb @@ -11,9 +11,9 @@ module ActiveModel private - def cast_value(value) - ::String.new(super) - end + def cast_value(value) + ::String.new(super) + end end end end diff --git a/activemodel/lib/active_model/type/text.rb b/activemodel/lib/active_model/type/text.rb index 1ad04daba4..7c0d647706 100644 --- a/activemodel/lib/active_model/type/text.rb +++ b/activemodel/lib/active_model/type/text.rb @@ -1,4 +1,4 @@ -require 'active_model/type/string' +require "active_model/type/string" module ActiveModel module Type diff --git a/activemodel/lib/active_model/type/time.rb b/activemodel/lib/active_model/type/time.rb index 34e09f0aba..54d6214e81 100644 --- a/activemodel/lib/active_model/type/time.rb +++ b/activemodel/lib/active_model/type/time.rb @@ -25,22 +25,22 @@ module ActiveModel private - def cast_value(value) - return value unless value.is_a?(::String) - return if value.empty? - - if value =~ /^2000-01-01/ - dummy_time_value = value - else - dummy_time_value = "2000-01-01 #{value}" + def cast_value(value) + return value unless value.is_a?(::String) + return if value.empty? + + if value.start_with?("2000-01-01") + dummy_time_value = value + else + dummy_time_value = "2000-01-01 #{value}" + end + + fast_string_to_time(dummy_time_value) || begin + time_hash = ::Date._parse(dummy_time_value) + return if time_hash[:hour].nil? + new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)) + end end - - fast_string_to_time(dummy_time_value) || begin - time_hash = ::Date._parse(dummy_time_value) - return if time_hash[:hour].nil? - new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)) - end - end end end end diff --git a/activemodel/lib/active_model/type/unsigned_integer.rb b/activemodel/lib/active_model/type/unsigned_integer.rb index 3f49f9f5f7..288fa23efe 100644 --- a/activemodel/lib/active_model/type/unsigned_integer.rb +++ b/activemodel/lib/active_model/type/unsigned_integer.rb @@ -3,13 +3,13 @@ module ActiveModel class UnsignedInteger < Integer # :nodoc: private - def max_value - super * 2 - end + def max_value + super * 2 + end - def min_value - 0 - end + def min_value + 0 + end end end end diff --git a/activemodel/lib/active_model/type/value.rb b/activemodel/lib/active_model/type/value.rb index 0d2d6873a8..7e9ae92245 100644 --- a/activemodel/lib/active_model/type/value.rb +++ b/activemodel/lib/active_model/type/value.rb @@ -105,12 +105,12 @@ module ActiveModel private - # Convenience method for types which do not need separate type casting - # behavior for user and database inputs. Called by Value#cast for - # values except +nil+. - def cast_value(value) # :doc: - value - end + # Convenience method for types which do not need separate type casting + # behavior for user and database inputs. Called by Value#cast for + # values except +nil+. + def cast_value(value) # :doc: + value + end end end end diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 8159b9b1d3..df6d3f2bcb 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -1,9 +1,8 @@ -require 'active_support/core_ext/array/extract_options' -require 'active_support/core_ext/hash/keys' -require 'active_support/core_ext/hash/except' +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/hash/keys" +require "active_support/core_ext/hash/except" module ActiveModel - # == Active \Model \Validations # # Provides a full validation framework to your objects. @@ -304,8 +303,6 @@ module ActiveModel # Runs all the specified validations and returns +true+ if no errors were # added otherwise +false+. # - # Aliased as validate. - # # class Person # include ActiveModel::Validations # diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb index a04e5f347e..4fadc795cd 100644 --- a/activemodel/lib/active_model/validations/acceptance.rb +++ b/activemodel/lib/active_model/validations/acceptance.rb @@ -1,5 +1,4 @@ module ActiveModel - module Validations class AcceptanceValidator < EachValidator # :nodoc: def initialize(options) @@ -15,58 +14,58 @@ 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 + 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 diff --git a/activemodel/lib/active_model/validations/callbacks.rb b/activemodel/lib/active_model/validations/callbacks.rb index 52111e5442..a201f72ed0 100644 --- a/activemodel/lib/active_model/validations/callbacks.rb +++ b/activemodel/lib/active_model/validations/callbacks.rb @@ -29,8 +29,7 @@ module ActiveModel 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 @@ -65,8 +64,7 @@ module ActiveModel set_callback(:validation, :before, *args, &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 diff --git a/activemodel/lib/active_model/validations/clusivity.rb b/activemodel/lib/active_model/validations/clusivity.rb index d49af603bb..18f1056e2b 100644 --- a/activemodel/lib/active_model/validations/clusivity.rb +++ b/activemodel/lib/active_model/validations/clusivity.rb @@ -1,4 +1,4 @@ -require 'active_support/core_ext/range' +require "active_support/core_ext/range" module ActiveModel module Validations @@ -16,12 +16,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..33ca6f6946 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -1,5 +1,4 @@ module ActiveModel - module Validations class ConfirmationValidator < EachValidator # :nodoc: def initialize(options) @@ -17,23 +16,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 diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb index 6f4276cc2a..82a1893823 100644 --- a/activemodel/lib/active_model/validations/exclusion.rb +++ b/activemodel/lib/active_model/validations/exclusion.rb @@ -1,7 +1,6 @@ require "active_model/validations/clusivity" module ActiveModel - module Validations class ExclusionValidator < EachValidator # :nodoc: include Clusivity diff --git a/activemodel/lib/active_model/validations/format.rb b/activemodel/lib/active_model/validations/format.rb index 46a2e54fba..e4ea42f8f4 100644 --- a/activemodel/lib/active_model/validations/format.rb +++ b/activemodel/lib/active_model/validations/format.rb @@ -1,5 +1,6 @@ -module ActiveModel +require "active_support/core_ext/regexp" +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 diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb index 03e0ef56d8..0ea6012a5d 100644 --- a/activemodel/lib/active_model/validations/inclusion.rb +++ b/activemodel/lib/active_model/validations/inclusion.rb @@ -1,7 +1,6 @@ require "active_model/validations/clusivity" module ActiveModel - module Validations class InclusionValidator < EachValidator # :nodoc: include Clusivity diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index 79297ac119..c924c8d2f8 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -46,7 +46,7 @@ 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| @@ -80,24 +80,23 @@ 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 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: diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index ad7012df48..48e0e5c9f6 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -1,5 +1,4 @@ module ActiveModel - module Validations class NumericalityValidator < EachValidator # :nodoc: CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=, @@ -27,8 +26,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 @@ -99,10 +96,10 @@ module ActiveModel 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) - end + 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) + end end module HelperMethods @@ -120,7 +117,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. diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb index 5d593274eb..0c11cf4265 100644 --- a/activemodel/lib/active_model/validations/presence.rb +++ b/activemodel/lib/active_model/validations/presence.rb @@ -1,6 +1,5 @@ module ActiveModel - module Validations class PresenceValidator < EachValidator # :nodoc: def validate_each(record, attr_name, value) diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index 1da4df21e7..c3cbb6e291 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -1,4 +1,4 @@ -require 'active_support/core_ext/hash/slice' +require "active_support/core_ext/hash/slice" module ActiveModel module Validations @@ -115,7 +115,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 diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index 699f74ed17..9c6065f61f 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -1,7 +1,6 @@ require "active_support/core_ext/module/anonymous" module ActiveModel - # == Active \Model \Validator # # A simple base class that can be used along with @@ -100,7 +99,7 @@ module ActiveModel # PresenceValidator.kind # => :presence # UniquenessValidator.kind # => :uniqueness def self.kind - @kind ||= name.split('::').last.underscore.chomp('_validator').to_sym unless anonymous? + @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous? end # Accepts options that will be made available through the +options+ reader. @@ -175,8 +174,8 @@ module ActiveModel private - def validate_each(record, attribute, value) - @block.call(record, attribute, value) - end + def validate_each(record, attribute, value) + @block.call(record, attribute, value) + end end end diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb index 6da3b4117b..6e7fd227fd 100644 --- a/activemodel/lib/active_model/version.rb +++ b/activemodel/lib/active_model/version.rb @@ -1,4 +1,4 @@ -require_relative 'gem_version' +require_relative "gem_version" module ActiveModel # Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt> |