All Files ( 91.69% covered at 62.48 hits/line )
    63 files in total.
  
  
    2371 relevant lines,
    2174 lines covered and
    197 lines missed. 
    (
  91.69%
)
  
  
  
    
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
#--
           
        
      
        
          - 
            
            
            
            
# Copyright (c) 2004-2020 David Heinemeier Hansson
           
        
      
        
          - 
            
            
            
            
#
           
        
      
        
          - 
            
            
            
            
# Permission is hereby granted, free of charge, to any person obtaining
           
        
      
        
          - 
            
            
            
            
# a copy of this software and associated documentation files (the
           
        
      
        
          - 
            
            
            
            
# "Software"), to deal in the Software without restriction, including
           
        
      
        
          - 
            
            
            
            
# without limitation the rights to use, copy, modify, merge, publish,
           
        
      
        
          - 
            
            
            
            
# distribute, sublicense, and/or sell copies of the Software, and to
           
        
      
        
          - 
            
            
            
            
# permit persons to whom the Software is furnished to do so, subject to
           
        
      
        
          - 
            
            
            
            
# the following conditions:
           
        
      
        
          - 
            
            
            
            
#
           
        
      
        
          - 
            
            
            
            
# The above copyright notice and this permission notice shall be
           
        
      
        
          - 
            
            
            
            
# included in all copies or substantial portions of the Software.
           
        
      
        
          - 
            
            
            
            
#
           
        
      
        
          - 
            
            
            
            
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
           
        
      
        
          - 
            
            
            
            
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
           
        
      
        
          - 
            
            
            
            
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
           
        
      
        
          - 
            
            
            
            
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
           
        
      
        
          - 
            
            
            
            
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
           
        
      
        
          - 
            
            
            
            
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
           
        
      
        
          - 
            
            
            
            
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
           
        
      
        
          - 
            
            
            
            
#++
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support"
           
        
      
        
          - 
            1
            
            
            
require "active_support/rails"
           
        
      
        
          - 
            1
            
            
            
require "active_model/version"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  extend ActiveSupport::Autoload
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  autoload :Attribute
           
        
      
        
          - 
            1
            
            
            
  autoload :Attributes
           
        
      
        
          - 
            1
            
            
            
  autoload :AttributeAssignment
           
        
      
        
          - 
            1
            
            
            
  autoload :AttributeMethods
           
        
      
        
          - 
            1
            
            
            
  autoload :BlockValidator, "active_model/validator"
           
        
      
        
          - 
            1
            
            
            
  autoload :Callbacks
           
        
      
        
          - 
            1
            
            
            
  autoload :Conversion
           
        
      
        
          - 
            1
            
            
            
  autoload :Dirty
           
        
      
        
          - 
            1
            
            
            
  autoload :EachValidator, "active_model/validator"
           
        
      
        
          - 
            1
            
            
            
  autoload :ForbiddenAttributesProtection
           
        
      
        
          - 
            1
            
            
            
  autoload :Lint
           
        
      
        
          - 
            1
            
            
            
  autoload :Model
           
        
      
        
          - 
            1
            
            
            
  autoload :Name, "active_model/naming"
           
        
      
        
          - 
            1
            
            
            
  autoload :Naming
           
        
      
        
          - 
            1
            
            
            
  autoload :SecurePassword
           
        
      
        
          - 
            1
            
            
            
  autoload :Serialization
           
        
      
        
          - 
            1
            
            
            
  autoload :Translation
           
        
      
        
          - 
            1
            
            
            
  autoload :Type
           
        
      
        
          - 
            1
            
            
            
  autoload :Validations
           
        
      
        
          - 
            1
            
            
            
  autoload :Validator
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  eager_autoload do
           
        
      
        
          - 
            1
            
            
            
    autoload :Errors
           
        
      
        
          - 
            1
            
            
            
    autoload :Error
           
        
      
        
          - 
            1
            
            
            
    autoload :RangeError, "active_model/errors"
           
        
      
        
          - 
            1
            
            
            
    autoload :StrictValidationFailed, "active_model/errors"
           
        
      
        
          - 
            1
            
            
            
    autoload :UnknownAttributeError, "active_model/errors"
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  module Serializers
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Autoload
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    eager_autoload do
           
        
      
        
          - 
            1
            
            
            
      autoload :JSON
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  def self.eager_load!
           
        
      
        
          - 
            
            
            
            
    super
           
        
      
        
          - 
            
            
            
            
    ActiveModel::Serializers.eager_load!
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
ActiveSupport.on_load(:i18n) do
           
        
      
        
          - 
            1
            
            
            
  I18n.load_path << File.expand_path("active_model/locale/en.yml", __dir__)
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/object/duplicable"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    class << self
           
        
      
        
          - 
            1
            
            
            
      def from_database(name, value_before_type_cast, type, value = nil)
           
        
      
        
          - 
            110
            
            
            
        FromDatabase.new(name, value_before_type_cast, type, nil, value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def from_user(name, value_before_type_cast, type, original_attribute = nil)
           
        
      
        
          - 
            65
            
            
            
        FromUser.new(name, value_before_type_cast, type, original_attribute)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def with_cast_value(name, value_before_type_cast, type)
           
        
      
        
          - 
            9
            
            
            
        WithCastValue.new(name, value_before_type_cast, type)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def null(name)
           
        
      
        
          - 
            11
            
            
            
        Null.new(name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def uninitialized(name, type)
           
        
      
        
          - 
            11
            
            
            
        Uninitialized.new(name, type)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    attr_reader :name, :value_before_type_cast, :type
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # This method should not be called directly.
           
        
      
        
          - 
            
            
            
            
    # Use #from_database or #from_user
           
        
      
        
          - 
            1
            
            
            
    def initialize(name, value_before_type_cast, type, original_attribute = nil, value = nil)
           
        
      
        
          - 
            210
            
            
            
      @name = name
           
        
      
        
          - 
            210
            
            
            
      @value_before_type_cast = value_before_type_cast
           
        
      
        
          - 
            210
            
            
            
      @type = type
           
        
      
        
          - 
            210
            
            
            
      @original_attribute = original_attribute
           
        
      
        
          - 
            210
            
            
            
      @value = value unless value.nil?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def value
           
        
      
        
          - 
            
            
            
            
      # `defined?` is cheaper than `||=` when we get back falsy values
           
        
      
        
          - 
            220
            
            
            
      @value = type_cast(value_before_type_cast) unless defined?(@value)
           
        
      
        
          - 
            220
            
            
            
      @value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def original_value
           
        
      
        
          - 
            124
            
            
            
      if assigned?
           
        
      
        
          - 
            62
            
            
            
        original_attribute.original_value
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            62
            
            
            
        type_cast(value_before_type_cast)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def value_for_database
           
        
      
        
          - 
            49
            
            
            
      type.serialize(value)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed?
           
        
      
        
          - 
            103
            
            
            
      changed_from_assignment? || changed_in_place?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_in_place?
           
        
      
        
          - 
            41
            
            
            
      has_been_read? && type.changed_in_place?(original_value_for_database, value)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def forgetting_assignment
           
        
      
        
          - 
            47
            
            
            
      with_value_from_database(value_for_database)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def with_value_from_user(value)
           
        
      
        
          - 
            61
            
            
            
      type.assert_valid_value(value)
           
        
      
        
          - 
            60
            
            
            
      self.class.from_user(name, value, type, original_attribute || self)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def with_value_from_database(value)
           
        
      
        
          - 
            51
            
            
            
      self.class.from_database(name, value, type)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def with_cast_value(value)
           
        
      
        
          - 
            2
            
            
            
      self.class.with_cast_value(name, value, type)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def with_type(type)
           
        
      
        
          - 
            2
            
            
            
      if changed_in_place?
           
        
      
        
          - 
            
            
            
            
        with_value_from_user(value).with_type(type)
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            2
            
            
            
        self.class.new(name, value_before_type_cast, type, original_attribute)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def type_cast(*)
           
        
      
        
          - 
            
            
            
            
      raise NotImplementedError
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialized?
           
        
      
        
          - 
            126
            
            
            
      true
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def came_from_user?
           
        
      
        
          - 
            
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def has_been_read?
           
        
      
        
          - 
            47
            
            
            
      defined?(@value)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def ==(other)
           
        
      
        
          - 
            14
            
            
            
      self.class == other.class &&
           
        
      
        
          - 
            
            
            
            
        name == other.name &&
           
        
      
        
          - 
            
            
            
            
        value_before_type_cast == other.value_before_type_cast &&
           
        
      
        
          - 
            
            
            
            
        type == other.type
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    alias eql? ==
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def hash
           
        
      
        
          - 
            
            
            
            
      [self.class, name, value_before_type_cast, type].hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def init_with(coder)
           
        
      
        
          - 
            
            
            
            
      @name = coder["name"]
           
        
      
        
          - 
            
            
            
            
      @value_before_type_cast = coder["value_before_type_cast"]
           
        
      
        
          - 
            
            
            
            
      @type = coder["type"]
           
        
      
        
          - 
            
            
            
            
      @original_attribute = coder["original_attribute"]
           
        
      
        
          - 
            
            
            
            
      @value = coder["value"] if coder.map.key?("value")
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def encode_with(coder)
           
        
      
        
          - 
            
            
            
            
      coder["name"] = name
           
        
      
        
          - 
            
            
            
            
      coder["value_before_type_cast"] = value_before_type_cast unless value_before_type_cast.nil?
           
        
      
        
          - 
            
            
            
            
      coder["type"] = type if type
           
        
      
        
          - 
            
            
            
            
      coder["original_attribute"] = original_attribute if original_attribute
           
        
      
        
          - 
            
            
            
            
      coder["value"] = value if defined?(@value)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def original_value_for_database
           
        
      
        
          - 
            13
            
            
            
      if assigned?
           
        
      
        
          - 
            4
            
            
            
        original_attribute.original_value_for_database
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            9
            
            
            
        _original_value_for_database
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      attr_reader :original_attribute
           
        
      
        
          - 
            1
            
            
            
      alias :assigned? :original_attribute
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize_dup(other)
           
        
      
        
          - 
            150
            
            
            
        if defined?(@value) && @value.duplicable?
           
        
      
        
          - 
            4
            
            
            
          @value = @value.dup
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def changed_from_assignment?
           
        
      
        
          - 
            103
            
            
            
        assigned? && type.changed?(original_value, value, value_before_type_cast)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _original_value_for_database
           
        
      
        
          - 
            
            
            
            
        type.serialize(original_value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class FromDatabase < Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        def type_cast(value)
           
        
      
        
          - 
            68
            
            
            
          type.deserialize(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def _original_value_for_database
           
        
      
        
          - 
            9
            
            
            
          value_before_type_cast
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            1
            
            
            
        private :_original_value_for_database
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class FromUser < Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        def type_cast(value)
           
        
      
        
          - 
            70
            
            
            
          type.cast(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def came_from_user?
           
        
      
        
          - 
            
            
            
            
          !type.value_constructed_by_mass_assignment?(value_before_type_cast)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class WithCastValue < Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        def type_cast(value)
           
        
      
        
          - 
            69
            
            
            
          value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def changed_in_place?
           
        
      
        
          - 
            28
            
            
            
          false
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class Null < Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        def initialize(name)
           
        
      
        
          - 
            11
            
            
            
          super(name, nil, Type.default_value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def type_cast(*)
           
        
      
        
          - 
            
            
            
            
          nil
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def with_type(type)
           
        
      
        
          - 
            7
            
            
            
          self.class.with_cast_value(name, nil, type)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def with_value_from_database(value)
           
        
      
        
          - 
            
            
            
            
          raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            1
            
            
            
        alias_method :with_value_from_user, :with_value_from_database
           
        
      
        
          - 
            1
            
            
            
        alias_method :with_cast_value, :with_value_from_database
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class Uninitialized < Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        UNINITIALIZED_ORIGINAL_VALUE = Object.new
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def initialize(name, type)
           
        
      
        
          - 
            11
            
            
            
          super(name, nil, type)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def value
           
        
      
        
          - 
            7
            
            
            
          if block_given?
           
        
      
        
          - 
            3
            
            
            
            yield name
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def original_value
           
        
      
        
          - 
            
            
            
            
          UNINITIALIZED_ORIGINAL_VALUE
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def value_for_database
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def initialized?
           
        
      
        
          - 
            4
            
            
            
          false
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def forgetting_assignment
           
        
      
        
          - 
            
            
            
            
          dup
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def with_type(type)
           
        
      
        
          - 
            
            
            
            
          self.class.new(name, type)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class Attribute # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    class UserProvidedDefault < FromUser # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def initialize(name, value, type, database_default)
           
        
      
        
          - 
            2
            
            
            
        @user_provided_value = value
           
        
      
        
          - 
            2
            
            
            
        super(name, value, type, database_default)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def value_before_type_cast
           
        
      
        
          - 
            14
            
            
            
        if user_provided_value.is_a?(Proc)
           
        
      
        
          - 
            6
            
            
            
          @memoized_value_before_type_cast ||= user_provided_value.call
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            8
            
            
            
          @user_provided_value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def with_type(type)
           
        
      
        
          - 
            
            
            
            
        self.class.new(name, user_provided_value, type, original_attribute)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def marshal_dump
           
        
      
        
          - 
            2
            
            
            
        result = [
           
        
      
        
          - 
            
            
            
            
          name,
           
        
      
        
          - 
            
            
            
            
          value_before_type_cast,
           
        
      
        
          - 
            
            
            
            
          type,
           
        
      
        
          - 
            
            
            
            
          original_attribute,
           
        
      
        
          - 
            
            
            
            
        ]
           
        
      
        
          - 
            2
            
            
            
        result << value if defined?(@value)
           
        
      
        
          - 
            2
            
            
            
        result
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def marshal_load(values)
           
        
      
        
          - 
            2
            
            
            
        name, user_provided_value, type, original_attribute, value = values
           
        
      
        
          - 
            2
            
            
            
        @name = name
           
        
      
        
          - 
            2
            
            
            
        @user_provided_value = user_provided_value
           
        
      
        
          - 
            2
            
            
            
        @type = type
           
        
      
        
          - 
            2
            
            
            
        @original_attribute = original_attribute
           
        
      
        
          - 
            2
            
            
            
        if values.length == 5
           
        
      
        
          - 
            2
            
            
            
          @value = value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        attr_reader :user_provided_value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/hash/keys"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module AttributeAssignment
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::ForbiddenAttributesProtection
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Allows you to set all the attributes by passing in a hash of attributes with
           
        
      
        
          - 
            
            
            
            
    # keys matching the attribute names.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If the passed hash responds to <tt>permitted?</tt> method and the return value
           
        
      
        
          - 
            
            
            
            
    # of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
           
        
      
        
          - 
            
            
            
            
    # exception is raised.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Cat
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::AttributeAssignment
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name, :status
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   cat = Cat.new
           
        
      
        
          - 
            
            
            
            
    #   cat.assign_attributes(name: "Gorby", status: "yawning")
           
        
      
        
          - 
            
            
            
            
    #   cat.name # => 'Gorby'
           
        
      
        
          - 
            
            
            
            
    #   cat.status # => 'yawning'
           
        
      
        
          - 
            
            
            
            
    #   cat.assign_attributes(status: "sleeping")
           
        
      
        
          - 
            
            
            
            
    #   cat.name # => 'Gorby'
           
        
      
        
          - 
            
            
            
            
    #   cat.status # => 'sleeping'
           
        
      
        
          - 
            1
            
            
            
    def assign_attributes(new_attributes)
           
        
      
        
          - 
            66
            
            
            
      unless new_attributes.respond_to?(:each_pair)
           
        
      
        
          - 
            1
            
            
            
        raise ArgumentError, "When assigning attributes, you must pass a hash as an argument, #{new_attributes.class} passed."
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            65
            
            
            
      return if new_attributes.empty?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            19
            
            
            
      _assign_attributes(sanitize_for_mass_assignment(new_attributes))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    alias attributes= assign_attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def _assign_attributes(attributes)
           
        
      
        
          - 
            18
            
            
            
        attributes.each do |k, v|
           
        
      
        
          - 
            28
            
            
            
          _assign_attribute(k, v)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _assign_attribute(k, v)
           
        
      
        
          - 
            28
            
            
            
        setter = :"#{k}="
           
        
      
        
          - 
            28
            
            
            
        if respond_to?(setter)
           
        
      
        
          - 
            24
            
            
            
          public_send(setter, v)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            4
            
            
            
          raise UnknownAttributeError.new(self, k.to_s)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "concurrent/map"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # Raised when an attribute is not defined.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class User < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
  #     has_many :pets
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   user = User.first
           
        
      
        
          - 
            
            
            
            
  #   user.pets.select(:id).first.user_id
           
        
      
        
          - 
            
            
            
            
  #   # => ActiveModel::MissingAttributeError: missing attribute: user_id
           
        
      
        
          - 
            1
            
            
            
  class MissingAttributeError < NoMethodError
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Attribute \Methods
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides a way to add prefixes and suffixes to your methods as
           
        
      
        
          - 
            
            
            
            
  # well as handling the creation of <tt>ActiveRecord::Base</tt>-like
           
        
      
        
          - 
            
            
            
            
  # class methods such as +table_name+.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # The requirements to implement <tt>ActiveModel::AttributeMethods</tt> are to:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # * <tt>include ActiveModel::AttributeMethods</tt> in your class.
           
        
      
        
          - 
            
            
            
            
  # * Call each of its methods you want to add, such as +attribute_method_suffix+
           
        
      
        
          - 
            
            
            
            
  #   or +attribute_method_prefix+.
           
        
      
        
          - 
            
            
            
            
  # * Call +define_attribute_methods+ after the other methods are called.
           
        
      
        
          - 
            
            
            
            
  # * Define the various generic +_attribute+ methods that you have declared.
           
        
      
        
          - 
            
            
            
            
  # * Define an +attributes+ method which returns a hash with each
           
        
      
        
          - 
            
            
            
            
  #   attribute name in your model as hash key and the attribute value as hash value.
           
        
      
        
          - 
            
            
            
            
  #   Hash keys must be strings.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attribute_method_affix  prefix: 'reset_', suffix: '_to_default!'
           
        
      
        
          - 
            
            
            
            
  #     attribute_method_suffix '_contrived?'
           
        
      
        
          - 
            
            
            
            
  #     attribute_method_prefix 'clear_'
           
        
      
        
          - 
            
            
            
            
  #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def attributes
           
        
      
        
          - 
            
            
            
            
  #       { 'name' => @name }
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     private
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def attribute_contrived?(attr)
           
        
      
        
          - 
            
            
            
            
  #       true
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def clear_attribute(attr)
           
        
      
        
          - 
            
            
            
            
  #       send("#{attr}=", nil)
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def reset_attribute_to_default!(attr)
           
        
      
        
          - 
            
            
            
            
  #       send("#{attr}=", 'Default Name')
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            1
            
            
            
  module AttributeMethods
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    NAME_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?=]?\z/
           
        
      
        
          - 
            1
            
            
            
    CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    included do
           
        
      
        
          - 
            10
            
            
            
      class_attribute :attribute_aliases, instance_writer: false, default: {}
           
        
      
        
          - 
            10
            
            
            
      class_attribute :attribute_method_matchers, instance_writer: false, default: [ ClassMethods::AttributeMethodMatcher.new ]
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            
            
            
            
      # Declares a method available for all attributes with the given prefix.
           
        
      
        
          - 
            
            
            
            
      # Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   #{prefix}#{attr}(*args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # to
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   #{prefix}attribute(#{attr}, *args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # An instance method <tt>#{prefix}attribute</tt> must exist and accept
           
        
      
        
          - 
            
            
            
            
      # at least the +attr+ argument.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_prefix 'clear_'
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def clear_attribute(attr)
           
        
      
        
          - 
            
            
            
            
      #       send("#{attr}=", nil)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
      #   person.name          # => "Bob"
           
        
      
        
          - 
            
            
            
            
      #   person.clear_name
           
        
      
        
          - 
            
            
            
            
      #   person.name          # => nil
           
        
      
        
          - 
            1
            
            
            
      def attribute_method_prefix(*prefixes)
           
        
      
        
          - 
            
            
            
            
        self.attribute_method_matchers += prefixes.map! { |prefix| AttributeMethodMatcher.new prefix: prefix }
           
        
      
        
          - 
            
            
            
            
        undefine_attribute_methods
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Declares a method available for all attributes with the given suffix.
           
        
      
        
          - 
            
            
            
            
      # Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   #{attr}#{suffix}(*args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # to
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   attribute#{suffix}(#{attr}, *args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # An <tt>attribute#{suffix}</tt> instance method must exist and accept at
           
        
      
        
          - 
            
            
            
            
      # least the +attr+ argument.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_suffix '_short?'
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attribute_short?(attr)
           
        
      
        
          - 
            
            
            
            
      #       send(attr).length < 5
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
      #   person.name          # => "Bob"
           
        
      
        
          - 
            
            
            
            
      #   person.name_short?   # => true
           
        
      
        
          - 
            1
            
            
            
      def attribute_method_suffix(*suffixes)
           
        
      
        
          - 
            27
            
            
            
        self.attribute_method_matchers += suffixes.map! { |suffix| AttributeMethodMatcher.new suffix: suffix }
           
        
      
        
          - 
            8
            
            
            
        undefine_attribute_methods
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Declares a method available for all attributes with the given prefix
           
        
      
        
          - 
            
            
            
            
      # and suffix. Uses +method_missing+ and <tt>respond_to?</tt> to rewrite
           
        
      
        
          - 
            
            
            
            
      # the method.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   #{prefix}#{attr}#{suffix}(*args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # to
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   #{prefix}attribute#{suffix}(#{attr}, *args, &block)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # An <tt>#{prefix}attribute#{suffix}</tt> instance method must exist and
           
        
      
        
          - 
            
            
            
            
      # accept at least the +attr+ argument.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def reset_attribute_to_default!(attr)
           
        
      
        
          - 
            
            
            
            
      #       send("#{attr}=", 'Default Name')
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name                         # => 'Gem'
           
        
      
        
          - 
            
            
            
            
      #   person.reset_name_to_default!
           
        
      
        
          - 
            
            
            
            
      #   person.name                         # => 'Default Name'
           
        
      
        
          - 
            1
            
            
            
      def attribute_method_affix(*affixes)
           
        
      
        
          - 
            8
            
            
            
        self.attribute_method_matchers += affixes.map! { |affix| AttributeMethodMatcher.new prefix: affix[:prefix], suffix: affix[:suffix] }
           
        
      
        
          - 
            4
            
            
            
        undefine_attribute_methods
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Allows you to make aliases for attributes.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_suffix '_short?'
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     alias_attribute :nickname, :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attribute_short?(attr)
           
        
      
        
          - 
            
            
            
            
      #       send(attr).length < 5
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
      #   person.name            # => "Bob"
           
        
      
        
          - 
            
            
            
            
      #   person.nickname        # => "Bob"
           
        
      
        
          - 
            
            
            
            
      #   person.name_short?     # => true
           
        
      
        
          - 
            
            
            
            
      #   person.nickname_short? # => true
           
        
      
        
          - 
            1
            
            
            
      def alias_attribute(new_name, old_name)
           
        
      
        
          - 
            4
            
            
            
        self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s)
           
        
      
        
          - 
            4
            
            
            
        CodeGenerator.batch(self, __FILE__, __LINE__) do |owner|
           
        
      
        
          - 
            4
            
            
            
          attribute_method_matchers.each do |matcher|
           
        
      
        
          - 
            4
            
            
            
            matcher_new = matcher.method_name(new_name).to_s
           
        
      
        
          - 
            4
            
            
            
            matcher_old = matcher.method_name(old_name).to_s
           
        
      
        
          - 
            4
            
            
            
            define_proxy_call false, owner, matcher_new, matcher_old
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Is +new_name+ an alias?
           
        
      
        
          - 
            1
            
            
            
      def attribute_alias?(new_name)
           
        
      
        
          - 
            
            
            
            
        attribute_aliases.key? new_name.to_s
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns the original name for the alias +name+
           
        
      
        
          - 
            1
            
            
            
      def attribute_alias(name)
           
        
      
        
          - 
            
            
            
            
        attribute_aliases[name.to_s]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Declares the attributes that should be prefixed and suffixed by
           
        
      
        
          - 
            
            
            
            
      # <tt>ActiveModel::AttributeMethods</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # To use, pass attribute names (as strings or symbols). Be sure to declare
           
        
      
        
          - 
            
            
            
            
      # +define_attribute_methods+ after you define any prefix, suffix or affix
           
        
      
        
          - 
            
            
            
            
      # methods, or they will not hook in.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name, :age, :address
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_prefix 'clear_'
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     # Call to define_attribute_methods must appear after the
           
        
      
        
          - 
            
            
            
            
      #     # attribute_method_prefix, attribute_method_suffix or
           
        
      
        
          - 
            
            
            
            
      #     # attribute_method_affix declarations.
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_methods :name, :age, :address
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def clear_attribute(attr)
           
        
      
        
          - 
            
            
            
            
      #       send("#{attr}=", nil)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            1
            
            
            
      def define_attribute_methods(*attr_names)
           
        
      
        
          - 
            9
            
            
            
        CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
           
        
      
        
          - 
            23
            
            
            
          attr_names.flatten.each { |attr_name| define_attribute_method(attr_name, _owner: owner) }
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Declares an attribute that should be prefixed and suffixed by
           
        
      
        
          - 
            
            
            
            
      # <tt>ActiveModel::AttributeMethods</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # To use, pass an attribute name (as string or symbol). Be sure to declare
           
        
      
        
          - 
            
            
            
            
      # +define_attribute_method+ after you define any prefix, suffix or affix
           
        
      
        
          - 
            
            
            
            
      # method, or they will not hook in.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_suffix '_short?'
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     # Call to define_attribute_method must appear after the
           
        
      
        
          - 
            
            
            
            
      #     # attribute_method_prefix, attribute_method_suffix or
           
        
      
        
          - 
            
            
            
            
      #     # attribute_method_affix declarations.
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_method :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attribute_short?(attr)
           
        
      
        
          - 
            
            
            
            
      #       send(attr).length < 5
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
      #   person.name        # => "Bob"
           
        
      
        
          - 
            
            
            
            
      #   person.name_short? # => true
           
        
      
        
          - 
            1
            
            
            
      def define_attribute_method(attr_name, _owner: generated_attribute_methods)
           
        
      
        
          - 
            29
            
            
            
        CodeGenerator.batch(_owner, __FILE__, __LINE__) do |owner|
           
        
      
        
          - 
            29
            
            
            
          attribute_method_matchers.each do |matcher|
           
        
      
        
          - 
            105
            
            
            
            method_name = matcher.method_name(attr_name)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            105
            
            
            
            unless instance_method_already_implemented?(method_name)
           
        
      
        
          - 
            104
            
            
            
              generate_method = "define_method_#{matcher.target}"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            104
            
            
            
              if respond_to?(generate_method, true)
           
        
      
        
          - 
            10
            
            
            
                send(generate_method, attr_name.to_s, owner: owner)
           
        
      
        
          - 
            
            
            
            
              else
           
        
      
        
          - 
            94
            
            
            
                define_proxy_call true, owner, method_name, matcher.target, attr_name.to_s
           
        
      
        
          - 
            
            
            
            
              end
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            29
            
            
            
          attribute_method_matchers_cache.clear
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Removes all the previously dynamically defined methods from the class.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     attribute_method_suffix '_short?'
           
        
      
        
          - 
            
            
            
            
      #     define_attribute_method :name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attribute_short?(attr)
           
        
      
        
          - 
            
            
            
            
      #       send(attr).length < 5
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
      #   person.name_short? # => true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.undefine_attribute_methods
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person.name_short? # => NoMethodError
           
        
      
        
          - 
            1
            
            
            
      def undefine_attribute_methods
           
        
      
        
          - 
            21
            
            
            
        generated_attribute_methods.module_eval do
           
        
      
        
          - 
            21
            
            
            
          undef_method(*instance_methods)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            21
            
            
            
        attribute_method_matchers_cache.clear
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        class CodeGenerator
           
        
      
        
          - 
            1
            
            
            
          class << self
           
        
      
        
          - 
            1
            
            
            
            def batch(owner, path, line)
           
        
      
        
          - 
            42
            
            
            
              if owner.is_a?(CodeGenerator)
           
        
      
        
          - 
            14
            
            
            
                yield owner
           
        
      
        
          - 
            
            
            
            
              else
           
        
      
        
          - 
            28
            
            
            
                instance = new(owner, path, line)
           
        
      
        
          - 
            28
            
            
            
                result = yield instance
           
        
      
        
          - 
            28
            
            
            
                instance.execute
           
        
      
        
          - 
            28
            
            
            
                result
           
        
      
        
          - 
            
            
            
            
              end
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def initialize(owner, path, line)
           
        
      
        
          - 
            28
            
            
            
            @owner = owner
           
        
      
        
          - 
            28
            
            
            
            @path = path
           
        
      
        
          - 
            28
            
            
            
            @line = line
           
        
      
        
          - 
            28
            
            
            
            @sources = ["# frozen_string_literal: true\n"]
           
        
      
        
          - 
            28
            
            
            
            @renames = {}
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def <<(source_line)
           
        
      
        
          - 
            108
            
            
            
            @sources << source_line
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def rename_method(old_name, new_name)
           
        
      
        
          - 
            
            
            
            
            @renames[old_name] = new_name
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def execute
           
        
      
        
          - 
            28
            
            
            
            @owner.module_eval(@sources.join(";"), @path, @line - 1)
           
        
      
        
          - 
            28
            
            
            
            @renames.each do |old_name, new_name|
           
        
      
        
          - 
            
            
            
            
              @owner.alias_method new_name, old_name
           
        
      
        
          - 
            
            
            
            
              @owner.undef_method old_name
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            1
            
            
            
        private_constant :CodeGenerator
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def generated_attribute_methods
           
        
      
        
          - 
            164
            
            
            
          @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def instance_method_already_implemented?(method_name)
           
        
      
        
          - 
            105
            
            
            
          generated_attribute_methods.method_defined?(method_name)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # The methods +method_missing+ and +respond_to?+ of this module are
           
        
      
        
          - 
            
            
            
            
        # invoked often in a typical rails, both of which invoke the method
           
        
      
        
          - 
            
            
            
            
        # +matched_attribute_method+. The latter method iterates through an
           
        
      
        
          - 
            
            
            
            
        # array doing regular expression matches, which results in a lot of
           
        
      
        
          - 
            
            
            
            
        # object creations. Most of the time it returns a +nil+ match. As the
           
        
      
        
          - 
            
            
            
            
        # match result is always the same given a +method_name+, this cache is
           
        
      
        
          - 
            
            
            
            
        # used to alleviate the GC, which ultimately also speeds up the app
           
        
      
        
          - 
            
            
            
            
        # significantly (in our case our test suite finishes 10% faster with
           
        
      
        
          - 
            
            
            
            
        # this cache).
           
        
      
        
          - 
            1
            
            
            
        def attribute_method_matchers_cache
           
        
      
        
          - 
            1409
            
            
            
          @attribute_method_matchers_cache ||= Concurrent::Map.new(initial_capacity: 4)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def attribute_method_matchers_matching(method_name)
           
        
      
        
          - 
            1359
            
            
            
          attribute_method_matchers_cache.compute_if_absent(method_name) do
           
        
      
        
          - 
            44
            
            
            
            attribute_method_matchers.map { |matcher| matcher.match(method_name) }.compact
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # Define a method `name` in `mod` that dispatches to `send`
           
        
      
        
          - 
            
            
            
            
        # using the given `extra` args. This falls back on `define_method`
           
        
      
        
          - 
            
            
            
            
        # and `send` if the given names cannot be compiled.
           
        
      
        
          - 
            1
            
            
            
        def define_proxy_call(include_private, code_generator, name, target, *extra)
           
        
      
        
          - 
            98
            
            
            
          defn = if NAME_COMPILABLE_REGEXP.match?(name)
           
        
      
        
          - 
            95
            
            
            
            "def #{name}(*args)"
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            3
            
            
            
            "define_method(:'#{name}') do |*args|"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
          extra = (extra.map!(&:inspect) << "*args").join(", ")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
          body = if CALL_COMPILABLE_REGEXP.match?(target)
           
        
      
        
          - 
            97
            
            
            
            "#{"self." unless include_private}#{target}(#{extra})"
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            1
            
            
            
            "send(:'#{target}', #{extra})"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          code_generator <<
           
        
      
        
          - 
            
            
            
            
            defn <<
           
        
      
        
          - 
            
            
            
            
            body <<
           
        
      
        
          - 
            98
            
            
            
            "end" <<
           
        
      
        
          - 
            
            
            
            
            "ruby2_keywords(:'#{name}') if respond_to?(:ruby2_keywords, true)"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        class AttributeMethodMatcher #:nodoc:
           
        
      
        
          - 
            1
            
            
            
          attr_reader :prefix, :suffix, :target
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          AttributeMethodMatch = Struct.new(:target, :attr_name)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def initialize(options = {})
           
        
      
        
          - 
            33
            
            
            
            @prefix, @suffix = options.fetch(:prefix, ""), options.fetch(:suffix, "")
           
        
      
        
          - 
            33
            
            
            
            @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/
           
        
      
        
          - 
            33
            
            
            
            @target = "#{@prefix}attribute#{@suffix}"
           
        
      
        
          - 
            33
            
            
            
            @method_name = "#{prefix}%s#{suffix}"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def match(method_name)
           
        
      
        
          - 
            30
            
            
            
            if @regex =~ method_name
           
        
      
        
          - 
            19
            
            
            
              AttributeMethodMatch.new(target, $1)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def method_name(attr_name)
           
        
      
        
          - 
            113
            
            
            
            @method_name % attr_name
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Allows access to the object attributes, which are held in the hash
           
        
      
        
          - 
            
            
            
            
    # returned by <tt>attributes</tt>, as though they were first-class
           
        
      
        
          - 
            
            
            
            
    # methods. So a +Person+ class with a +name+ attribute can for example use
           
        
      
        
          - 
            
            
            
            
    # <tt>Person#name</tt> and <tt>Person#name=</tt> and never directly use
           
        
      
        
          - 
            
            
            
            
    # the attributes hash -- except for multiple assignments with
           
        
      
        
          - 
            
            
            
            
    # <tt>ActiveRecord::Base#attributes=</tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # It's also possible to instantiate related objects, so a <tt>Client</tt>
           
        
      
        
          - 
            
            
            
            
    # class belonging to the +clients+ table with a +master_id+ foreign key
           
        
      
        
          - 
            
            
            
            
    # can instantiate master through <tt>Client#master</tt>.
           
        
      
        
          - 
            1
            
            
            
    def method_missing(method, *args, &block)
           
        
      
        
          - 
            9
            
            
            
      if respond_to_without_attributes?(method, true)
           
        
      
        
          - 
            2
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            7
            
            
            
        match = matched_attribute_method(method.to_s)
           
        
      
        
          - 
            7
            
            
            
        match ? attribute_missing(match, *args, &block) : super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # +attribute_missing+ is like +method_missing+, but for attributes. When
           
        
      
        
          - 
            
            
            
            
    # +method_missing+ is called we check to see if there is a matching
           
        
      
        
          - 
            
            
            
            
    # attribute method. If so, we tell +attribute_missing+ to dispatch the
           
        
      
        
          - 
            
            
            
            
    # attribute. This method can be overloaded to customize the behavior.
           
        
      
        
          - 
            1
            
            
            
    def attribute_missing(match, *args, &block)
           
        
      
        
          - 
            3
            
            
            
      __send__(match.target, match.attr_name, *args, &block)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # A +Person+ instance with a +name+ attribute can ask
           
        
      
        
          - 
            
            
            
            
    # <tt>person.respond_to?(:name)</tt>, <tt>person.respond_to?(:name=)</tt>,
           
        
      
        
          - 
            
            
            
            
    # and <tt>person.respond_to?(:name?)</tt> which will all return +true+.
           
        
      
        
          - 
            1
            
            
            
    alias :respond_to_without_attributes? :respond_to?
           
        
      
        
          - 
            1
            
            
            
    def respond_to?(method, include_private_methods = false)
           
        
      
        
          - 
            1379
            
            
            
      if super
           
        
      
        
          - 
            25
            
            
            
        true
           
        
      
        
          - 
            1354
            
            
            
      elsif !include_private_methods && super(method, true)
           
        
      
        
          - 
            
            
            
            
        # If we're here then we haven't found among non-private methods
           
        
      
        
          - 
            
            
            
            
        # but found among all methods. Which means that the given method is private.
           
        
      
        
          - 
            2
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            1352
            
            
            
        !matched_attribute_method(method.to_s).nil?
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def attribute_method?(attr_name)
           
        
      
        
          - 
            1811
            
            
            
        respond_to_without_attributes?(:attributes) && attributes.include?(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns a struct representing the matching attribute method.
           
        
      
        
          - 
            
            
            
            
      # The struct's attributes are prefix, base and suffix.
           
        
      
        
          - 
            1
            
            
            
      def matched_attribute_method(method_name)
           
        
      
        
          - 
            1359
            
            
            
        matches = self.class.send(:attribute_method_matchers_matching, method_name)
           
        
      
        
          - 
            3170
            
            
            
        matches.detect { |match| attribute_method?(match.attr_name) }
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def missing_attribute(attr_name, stack)
           
        
      
        
          - 
            
            
            
            
        raise ActiveModel::MissingAttributeError, "missing attribute: #{attr_name}", stack
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _read_attribute(attr)
           
        
      
        
          - 
            67
            
            
            
        __send__(attr)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      module AttrNames # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        DEF_SAFE_NAME = /\A[a-zA-Z_]\w*\z/
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # We want to generate the methods via module_eval rather than
           
        
      
        
          - 
            
            
            
            
        # define_method, because define_method is slower on dispatch.
           
        
      
        
          - 
            
            
            
            
        # Evaluating many similar methods may use more memory as the instruction
           
        
      
        
          - 
            
            
            
            
        # sequences are duplicated and cached (in MRI).  define_method may
           
        
      
        
          - 
            
            
            
            
        # be slower on dispatch, but if you're careful about the closure
           
        
      
        
          - 
            
            
            
            
        # created, then define_method will consume much less memory.
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        # But sometimes the database might return columns with
           
        
      
        
          - 
            
            
            
            
        # characters that are not allowed in normal method names (like
           
        
      
        
          - 
            
            
            
            
        # 'my_column(omg)'. So to work around this we first define with
           
        
      
        
          - 
            
            
            
            
        # the __temp__ identifier, and then use alias method to rename
           
        
      
        
          - 
            
            
            
            
        # it to what we want.
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        # We are also defining a constant to hold the frozen string of
           
        
      
        
          - 
            
            
            
            
        # the attribute name. Using a constant means that we do not have
           
        
      
        
          - 
            
            
            
            
        # to allocate an object on each call to the attribute method.
           
        
      
        
          - 
            
            
            
            
        # Making it frozen means that it doesn't get duped when used to
           
        
      
        
          - 
            
            
            
            
        # key the @attributes in read_attribute.
           
        
      
        
          - 
            1
            
            
            
        def self.define_attribute_accessor_method(owner, attr_name, writer: false)
           
        
      
        
          - 
            10
            
            
            
          method_name = "#{attr_name}#{'=' if writer}"
           
        
      
        
          - 
            10
            
            
            
          if attr_name.ascii_only? && DEF_SAFE_NAME.match?(attr_name)
           
        
      
        
          - 
            10
            
            
            
            yield method_name, "'#{attr_name}'"
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            
            
            
            
            safe_name = attr_name.unpack1("h*")
           
        
      
        
          - 
            
            
            
            
            const_name = "ATTR_#{safe_name}"
           
        
      
        
          - 
            
            
            
            
            const_set(const_name, attr_name) unless const_defined?(const_name)
           
        
      
        
          - 
            
            
            
            
            temp_method_name = "__temp__#{safe_name}#{'=' if writer}"
           
        
      
        
          - 
            
            
            
            
            attr_name_expr = "::ActiveModel::AttributeMethods::AttrNames::#{const_name}"
           
        
      
        
          - 
            
            
            
            
            yield temp_method_name, attr_name_expr
           
        
      
        
          - 
            
            
            
            
            owner.rename_method(temp_method_name, method_name)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/hash/indifferent_access"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/object/duplicable"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class AttributeMutationTracker # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    OPTION_NOT_GIVEN = Object.new
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(attributes)
           
        
      
        
          - 
            61
            
            
            
      @attributes = attributes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_attribute_names
           
        
      
        
          - 
            18
            
            
            
      attr_names.select { |attr_name| changed?(attr_name) }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_values
           
        
      
        
          - 
            10
            
            
            
      attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
           
        
      
        
          - 
            20
            
            
            
        if changed?(attr_name)
           
        
      
        
          - 
            8
            
            
            
          result[attr_name] = original_value(attr_name)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changes
           
        
      
        
          - 
            27
            
            
            
      attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
           
        
      
        
          - 
            49
            
            
            
        if change = change_to_attribute(attr_name)
           
        
      
        
          - 
            34
            
            
            
          result.merge!(attr_name => change)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def change_to_attribute(attr_name)
           
        
      
        
          - 
            46
            
            
            
      if changed?(attr_name)
           
        
      
        
          - 
            31
            
            
            
        [original_value(attr_name), fetch_value(attr_name)]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def any_changes?
           
        
      
        
          - 
            46
            
            
            
      attr_names.any? { |attr| changed?(attr) }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed?(attr_name, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN)
           
        
      
        
          - 
            203
            
            
            
      attribute_changed?(attr_name) &&
           
        
      
        
          - 
            136
            
            
            
        (OPTION_NOT_GIVEN == from || original_value(attr_name) == from) &&
           
        
      
        
          - 
            130
            
            
            
        (OPTION_NOT_GIVEN == to || fetch_value(attr_name) == to)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_in_place?(attr_name)
           
        
      
        
          - 
            
            
            
            
      attributes[attr_name].changed_in_place?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def forget_change(attr_name)
           
        
      
        
          - 
            4
            
            
            
      attributes[attr_name] = attributes[attr_name].forgetting_assignment
           
        
      
        
          - 
            4
            
            
            
      forced_changes.delete(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def original_value(attr_name)
           
        
      
        
          - 
            20
            
            
            
      attributes[attr_name].original_value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def force_change(attr_name)
           
        
      
        
          - 
            
            
            
            
      forced_changes[attr_name] = fetch_value(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      attr_reader :attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def forced_changes
           
        
      
        
          - 
            370
            
            
            
        @forced_changes ||= {}
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def attr_names
           
        
      
        
          - 
            25
            
            
            
        attributes.keys
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def attribute_changed?(attr_name)
           
        
      
        
          - 
            97
            
            
            
        forced_changes.include?(attr_name) || !!attributes[attr_name].changed?
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def fetch_value(attr_name)
           
        
      
        
          - 
            11
            
            
            
        attributes.fetch_value(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class ForcedMutationTracker < AttributeMutationTracker # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    def initialize(attributes)
           
        
      
        
          - 
            30
            
            
            
      super
           
        
      
        
          - 
            30
            
            
            
      @finalized_changes = nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_in_place?(attr_name)
           
        
      
        
          - 
            
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def change_to_attribute(attr_name)
           
        
      
        
          - 
            31
            
            
            
      if finalized_changes&.include?(attr_name)
           
        
      
        
          - 
            8
            
            
            
        finalized_changes[attr_name].dup
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            23
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def forget_change(attr_name)
           
        
      
        
          - 
            4
            
            
            
      forced_changes.delete(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def original_value(attr_name)
           
        
      
        
          - 
            41
            
            
            
      if changed?(attr_name)
           
        
      
        
          - 
            41
            
            
            
        forced_changes[attr_name]
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            
            
            
            
        fetch_value(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def force_change(attr_name)
           
        
      
        
          - 
            44
            
            
            
      forced_changes[attr_name] = clone_value(attr_name) unless attribute_changed?(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def finalize_changes
           
        
      
        
          - 
            12
            
            
            
      @finalized_changes = changes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      attr_reader :finalized_changes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def attr_names
           
        
      
        
          - 
            36
            
            
            
        forced_changes.keys
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def attribute_changed?(attr_name)
           
        
      
        
          - 
            150
            
            
            
        forced_changes.include?(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def fetch_value(attr_name)
           
        
      
        
          - 
            67
            
            
            
        attributes.send(:_read_attribute, attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def clone_value(attr_name)
           
        
      
        
          - 
            38
            
            
            
        value = fetch_value(attr_name)
           
        
      
        
          - 
            38
            
            
            
        value.duplicable? ? value.clone : value
           
        
      
        
          - 
            
            
            
            
      rescue TypeError, NoMethodError
           
        
      
        
          - 
            
            
            
            
        value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class NullMutationTracker # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    include Singleton
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_attribute_names
           
        
      
        
          - 
            
            
            
            
      []
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_values
           
        
      
        
          - 
            
            
            
            
      {}
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changes
           
        
      
        
          - 
            2
            
            
            
      {}
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def change_to_attribute(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def any_changes?
           
        
      
        
          - 
            
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed?(attr_name, **)
           
        
      
        
          - 
            
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def changed_in_place?(attr_name)
           
        
      
        
          - 
            
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def original_value(attr_name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/enumerable"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/object/deep_dup"
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute_set/builder"
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute_set/yaml_encoder"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class AttributeSet # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    delegate :each_value, :fetch, :except, to: :attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(attributes)
           
        
      
        
          - 
            87
            
            
            
      @attributes = attributes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def [](name)
           
        
      
        
          - 
            448
            
            
            
      @attributes[name] || default_attribute(name)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def []=(name, value)
           
        
      
        
          - 
            14
            
            
            
      @attributes[name] = value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def values_before_type_cast
           
        
      
        
          - 
            1
            
            
            
      attributes.transform_values(&:value_before_type_cast)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def to_hash
           
        
      
        
          - 
            50
            
            
            
      keys.index_with { |name| self[name].value }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    alias :to_h :to_hash
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def key?(name)
           
        
      
        
          - 
            
            
            
            
      attributes.key?(name) && self[name].initialized?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def keys
           
        
      
        
          - 
            144
            
            
            
      attributes.each_key.select { |name| self[name].initialized? }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def fetch_value(name, &block)
           
        
      
        
          - 
            34
            
            
            
      self[name].value(&block)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def write_from_database(name, value)
           
        
      
        
          - 
            3
            
            
            
      @attributes[name] = self[name].with_value_from_database(value)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def write_from_user(name, value)
           
        
      
        
          - 
            56
            
            
            
      raise FrozenError, "can't modify frozen attributes" if frozen?
           
        
      
        
          - 
            55
            
            
            
      @attributes[name] = self[name].with_value_from_user(value)
           
        
      
        
          - 
            55
            
            
            
      value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def write_cast_value(name, value)
           
        
      
        
          - 
            
            
            
            
      @attributes[name] = self[name].with_cast_value(value)
           
        
      
        
          - 
            
            
            
            
      value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def freeze
           
        
      
        
          - 
            3
            
            
            
      attributes.freeze
           
        
      
        
          - 
            3
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def deep_dup
           
        
      
        
          - 
            41
            
            
            
      AttributeSet.new(attributes.deep_dup)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(_)
           
        
      
        
          - 
            1
            
            
            
      @attributes = @attributes.dup
           
        
      
        
          - 
            1
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_clone(_)
           
        
      
        
          - 
            2
            
            
            
      @attributes = @attributes.clone
           
        
      
        
          - 
            2
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def reset(key)
           
        
      
        
          - 
            
            
            
            
      if key?(key)
           
        
      
        
          - 
            
            
            
            
        write_from_database(key, nil)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def accessed
           
        
      
        
          - 
            6
            
            
            
      attributes.each_key.select { |name| self[name].has_been_read? }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def map(&block)
           
        
      
        
          - 
            15
            
            
            
      new_attributes = attributes.transform_values(&block)
           
        
      
        
          - 
            15
            
            
            
      AttributeSet.new(new_attributes)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def ==(other)
           
        
      
        
          - 
            3
            
            
            
      attributes == other.attributes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    protected
           
        
      
        
          - 
            1
            
            
            
      attr_reader :attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def default_attribute(name)
           
        
      
        
          - 
            7
            
            
            
        Attribute.null(name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class AttributeSet # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    class Builder # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      attr_reader :types, :default_attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize(types, default_attributes = {})
           
        
      
        
          - 
            26
            
            
            
        @types = types
           
        
      
        
          - 
            26
            
            
            
        @default_attributes = default_attributes
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def build_from_database(values = {}, additional_types = {})
           
        
      
        
          - 
            27
            
            
            
        LazyAttributeSet.new(values, types, additional_types, default_attributes)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class LazyAttributeSet < AttributeSet # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    def initialize(values, types, additional_types, default_attributes, attributes = {})
           
        
      
        
          - 
            27
            
            
            
      super(attributes)
           
        
      
        
          - 
            27
            
            
            
      @values = values
           
        
      
        
          - 
            27
            
            
            
      @types = types
           
        
      
        
          - 
            27
            
            
            
      @additional_types = additional_types
           
        
      
        
          - 
            27
            
            
            
      @default_attributes = default_attributes
           
        
      
        
          - 
            27
            
            
            
      @casted_values = {}
           
        
      
        
          - 
            27
            
            
            
      @materialized = false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def key?(name)
           
        
      
        
          - 
            4
            
            
            
      (values.key?(name) || types.key?(name) || @attributes.key?(name)) && self[name].initialized?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def keys
           
        
      
        
          - 
            7
            
            
            
      keys = values.keys | types.keys | @attributes.keys
           
        
      
        
          - 
            19
            
            
            
      keys.keep_if { |name| self[name].initialized? }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def fetch_value(name, &block)
           
        
      
        
          - 
            11
            
            
            
      if attr = @attributes[name]
           
        
      
        
          - 
            3
            
            
            
        return attr.value(&block)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            8
            
            
            
      @casted_values.fetch(name) do
           
        
      
        
          - 
            8
            
            
            
        value_present = true
           
        
      
        
          - 
            14
            
            
            
        value = values.fetch(name) { value_present = false }
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            8
            
            
            
        if value_present
           
        
      
        
          - 
            2
            
            
            
          type = additional_types.fetch(name, types[name])
           
        
      
        
          - 
            2
            
            
            
          @casted_values[name] = type.deserialize(value)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            6
            
            
            
          attr = default_attribute(name, value_present, value)
           
        
      
        
          - 
            6
            
            
            
          attr.value(&block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    protected
           
        
      
        
          - 
            1
            
            
            
      def attributes
           
        
      
        
          - 
            10
            
            
            
        unless @materialized
           
        
      
        
          - 
            23
            
            
            
          values.each_key { |key| self[key] }
           
        
      
        
          - 
            23
            
            
            
          types.each_key { |key| self[key] }
           
        
      
        
          - 
            8
            
            
            
          @materialized = true
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            10
            
            
            
        @attributes
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      attr_reader :values, :types, :additional_types, :default_attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def default_attribute(
           
        
      
        
          - 
            
            
            
            
        name,
           
        
      
        
          - 
            
            
            
            
        value_present = true,
           
        
      
        
          - 
            7
            
            
            
        value = values.fetch(name) { value_present = false }
           
        
      
        
          - 
            
            
            
            
      )
           
        
      
        
          - 
            43
            
            
            
        type = additional_types.fetch(name, types[name])
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            43
            
            
            
        if value_present
           
        
      
        
          - 
            30
            
            
            
          @attributes[name] = Attribute.from_database(name, value, type, @casted_values[name])
           
        
      
        
          - 
            13
            
            
            
        elsif types.key?(name)
           
        
      
        
          - 
            9
            
            
            
          if attr = default_attributes[name]
           
        
      
        
          - 
            1
            
            
            
            @attributes[name] = attr.dup
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            8
            
            
            
            @attributes[name] = Attribute.uninitialized(name, type)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            4
            
            
            
          Attribute.null(name)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class LazyAttributeHash # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    delegate :transform_values, :each_value, :fetch, :except, to: :materialize
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(types, values, additional_types, default_attributes, delegate_hash = {})
           
        
      
        
          - 
            2
            
            
            
      @types = types
           
        
      
        
          - 
            2
            
            
            
      @values = values
           
        
      
        
          - 
            2
            
            
            
      @additional_types = additional_types
           
        
      
        
          - 
            2
            
            
            
      @materialized = false
           
        
      
        
          - 
            2
            
            
            
      @delegate_hash = delegate_hash
           
        
      
        
          - 
            2
            
            
            
      @default_attributes = default_attributes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def key?(key)
           
        
      
        
          - 
            
            
            
            
      delegate_hash.key?(key) || values.key?(key) || types.key?(key)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def [](key)
           
        
      
        
          - 
            4
            
            
            
      delegate_hash[key] || assign_default_value(key)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def []=(key, value)
           
        
      
        
          - 
            
            
            
            
      delegate_hash[key] = value
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def deep_dup
           
        
      
        
          - 
            
            
            
            
      dup.tap do |copy|
           
        
      
        
          - 
            
            
            
            
        copy.instance_variable_set(:@delegate_hash, delegate_hash.transform_values(&:dup))
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(_)
           
        
      
        
          - 
            
            
            
            
      @delegate_hash = Hash[delegate_hash]
           
        
      
        
          - 
            
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def each_key(&block)
           
        
      
        
          - 
            1
            
            
            
      keys = types.keys | values.keys | delegate_hash.keys
           
        
      
        
          - 
            1
            
            
            
      keys.each(&block)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def ==(other)
           
        
      
        
          - 
            
            
            
            
      if other.is_a?(LazyAttributeHash)
           
        
      
        
          - 
            
            
            
            
        materialize == other.materialize
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            
            
            
            
        materialize == other
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def marshal_dump
           
        
      
        
          - 
            
            
            
            
      [@types, @values, @additional_types, @default_attributes, @delegate_hash]
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def marshal_load(values)
           
        
      
        
          - 
            1
            
            
            
      if values.is_a?(Hash)
           
        
      
        
          - 
            1
            
            
            
        ActiveSupport::Deprecation.warn(<<~MSG)
           
        
      
        
          - 
            
            
            
            
          Marshalling load from legacy attributes format is deprecated and will be removed in Rails 6.2.
           
        
      
        
          - 
            
            
            
            
        MSG
           
        
      
        
          - 
            1
            
            
            
        empty_hash = {}.freeze
           
        
      
        
          - 
            1
            
            
            
        initialize(empty_hash, empty_hash, empty_hash, empty_hash, values)
           
        
      
        
          - 
            1
            
            
            
        @materialized = true
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            
            
            
            
        initialize(*values)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    protected
           
        
      
        
          - 
            1
            
            
            
      def materialize
           
        
      
        
          - 
            1
            
            
            
        unless @materialized
           
        
      
        
          - 
            2
            
            
            
          values.each_key { |key| self[key] }
           
        
      
        
          - 
            2
            
            
            
          types.each_key { |key| self[key] }
           
        
      
        
          - 
            1
            
            
            
          unless frozen?
           
        
      
        
          - 
            1
            
            
            
            @materialized = true
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            1
            
            
            
        delegate_hash
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      attr_reader :types, :values, :additional_types, :delegate_hash, :default_attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def assign_default_value(name)
           
        
      
        
          - 
            1
            
            
            
        type = additional_types.fetch(name, types[name])
           
        
      
        
          - 
            1
            
            
            
        value_present = true
           
        
      
        
          - 
            1
            
            
            
        value = values.fetch(name) { value_present = false }
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        if value_present
           
        
      
        
          - 
            1
            
            
            
          delegate_hash[name] = Attribute.from_database(name, value, type)
           
        
      
        
          - 
            
            
            
            
        elsif types.key?(name)
           
        
      
        
          - 
            
            
            
            
          attr = default_attributes[name]
           
        
      
        
          - 
            
            
            
            
          if attr
           
        
      
        
          - 
            
            
            
            
            delegate_hash[name] = attr.dup
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            
            
            
            
            delegate_hash[name] = Attribute.uninitialized(name, type)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class AttributeSet
           
        
      
        
          - 
            
            
            
            
    # Attempts to do more intelligent YAML dumping of an
           
        
      
        
          - 
            
            
            
            
    # ActiveModel::AttributeSet to reduce the size of the resulting string
           
        
      
        
          - 
            1
            
            
            
    class YAMLEncoder # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def initialize(default_types)
           
        
      
        
          - 
            
            
            
            
        @default_types = default_types
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def encode(attribute_set, coder)
           
        
      
        
          - 
            
            
            
            
        coder["concise_attributes"] = attribute_set.each_value.map do |attr|
           
        
      
        
          - 
            
            
            
            
          if attr.type.equal?(default_types[attr.name])
           
        
      
        
          - 
            
            
            
            
            attr.with_type(nil)
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            
            
            
            
            attr
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def decode(coder)
           
        
      
        
          - 
            
            
            
            
        if coder["attributes"]
           
        
      
        
          - 
            
            
            
            
          coder["attributes"]
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            
            
            
            
          attributes_hash = Hash[coder["concise_attributes"].map do |attr|
           
        
      
        
          - 
            
            
            
            
            if attr.type.nil?
           
        
      
        
          - 
            
            
            
            
              attr = attr.with_type(default_types[attr.name])
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
            [attr.name, attr]
           
        
      
        
          - 
            
            
            
            
          end]
           
        
      
        
          - 
            
            
            
            
          AttributeSet.new(attributes_hash)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        attr_reader :default_types
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute_set"
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute/user_provided_default"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Attributes #:nodoc:
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    included do
           
        
      
        
          - 
            2
            
            
            
      attribute_method_suffix "="
           
        
      
        
          - 
            2
            
            
            
      class_attribute :attribute_types, :_default_attributes, instance_accessor: false
           
        
      
        
          - 
            2
            
            
            
      self.attribute_types = Hash.new(Type.default_value)
           
        
      
        
          - 
            2
            
            
            
      self._default_attributes = AttributeSet.new({})
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            1
            
            
            
      def attribute(name, type = Type::Value.new, **options)
           
        
      
        
          - 
            10
            
            
            
        name = name.to_s
           
        
      
        
          - 
            10
            
            
            
        if type.is_a?(Symbol)
           
        
      
        
          - 
            10
            
            
            
          type = ActiveModel::Type.lookup(type, **options.except(:default))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            10
            
            
            
        self.attribute_types = attribute_types.merge(name => type)
           
        
      
        
          - 
            10
            
            
            
        define_default_attribute(name, options.fetch(:default, NO_DEFAULT_PROVIDED), type)
           
        
      
        
          - 
            10
            
            
            
        define_attribute_method(name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns an array of attribute names as strings
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Attributes
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attribute :name, :string
           
        
      
        
          - 
            
            
            
            
      #     attribute :age, :integer
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.attribute_names
           
        
      
        
          - 
            
            
            
            
      #   # => ["name", "age"]
           
        
      
        
          - 
            1
            
            
            
      def attribute_names
           
        
      
        
          - 
            1
            
            
            
        attribute_types.keys
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def define_method_attribute=(name, owner:)
           
        
      
        
          - 
            
            
            
            
          ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
           
        
      
        
          - 
            
            
            
            
            owner, name, writer: true,
           
        
      
        
          - 
            10
            
            
            
          ) do |temp_method_name, attr_name_expr|
           
        
      
        
          - 
            
            
            
            
            owner <<
           
        
      
        
          - 
            
            
            
            
              "def #{temp_method_name}(value)" <<
           
        
      
        
          - 
            10
            
            
            
              "  _write_attribute(#{attr_name_expr}, value)" <<
           
        
      
        
          - 
            
            
            
            
              "end"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        NO_DEFAULT_PROVIDED = Object.new # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        private_constant :NO_DEFAULT_PROVIDED
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def define_default_attribute(name, value, type)
           
        
      
        
          - 
            10
            
            
            
          self._default_attributes = _default_attributes.deep_dup
           
        
      
        
          - 
            10
            
            
            
          if value == NO_DEFAULT_PROVIDED
           
        
      
        
          - 
            8
            
            
            
            default_attribute = _default_attributes[name].with_type(type)
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            2
            
            
            
            default_attribute = Attribute::UserProvidedDefault.new(
           
        
      
        
          - 
            
            
            
            
              name,
           
        
      
        
          - 
            
            
            
            
              value,
           
        
      
        
          - 
            
            
            
            
              type,
           
        
      
        
          - 
            2
            
            
            
              _default_attributes.fetch(name.to_s) { nil },
           
        
      
        
          - 
            
            
            
            
            )
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            10
            
            
            
          _default_attributes[name] = default_attribute
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(*)
           
        
      
        
          - 
            29
            
            
            
      @attributes = self.class._default_attributes.deep_dup
           
        
      
        
          - 
            29
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(other) # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      @attributes = @attributes.deep_dup
           
        
      
        
          - 
            1
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Attributes
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attribute :name, :string
           
        
      
        
          - 
            
            
            
            
    #     attribute :age, :integer
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new(name: 'Francesco', age: 22)
           
        
      
        
          - 
            
            
            
            
    #   person.attributes
           
        
      
        
          - 
            
            
            
            
    #   # => {"name"=>"Francesco", "age"=>22}
           
        
      
        
          - 
            1
            
            
            
    def attributes
           
        
      
        
          - 
            5
            
            
            
      @attributes.to_hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns an array of attribute names as strings
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Attributes
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attribute :name, :string
           
        
      
        
          - 
            
            
            
            
    #     attribute :age, :integer
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.attribute_names
           
        
      
        
          - 
            
            
            
            
    #   # => ["name", "age"]
           
        
      
        
          - 
            1
            
            
            
    def attribute_names
           
        
      
        
          - 
            1
            
            
            
      @attributes.keys
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def freeze
           
        
      
        
          - 
            1
            
            
            
      @attributes = @attributes.clone.freeze
           
        
      
        
          - 
            1
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def write_attribute(attr_name, value)
           
        
      
        
          - 
            
            
            
            
        name = attr_name.to_s
           
        
      
        
          - 
            
            
            
            
        name = self.class.attribute_aliases[name] || name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        @attributes.write_from_user(name, value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _write_attribute(attr_name, value)
           
        
      
        
          - 
            55
            
            
            
        @attributes.write_from_user(attr_name, value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            1
            
            
            
      alias :attribute= :_write_attribute
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def read_attribute(attr_name)
           
        
      
        
          - 
            
            
            
            
        name = attr_name.to_s
           
        
      
        
          - 
            
            
            
            
        name = self.class.attribute_aliases[name] || name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        @attributes.fetch_value(name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def attribute(attr_name)
           
        
      
        
          - 
            21
            
            
            
        @attributes.fetch_value(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/array/extract_options"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/hash/keys"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Callbacks
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides an interface for any class to have Active Record like callbacks.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Like the Active Record methods, the callback chain is aborted as soon as
           
        
      
        
          - 
            
            
            
            
  # one of the methods throws +:abort+.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # First, extend ActiveModel::Callbacks from the class you are creating:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyModel
           
        
      
        
          - 
            
            
            
            
  #     extend ActiveModel::Callbacks
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Then define a list of methods that you want callbacks attached to:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   define_model_callbacks :create, :update
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # This will provide all three standard callbacks (before, around and after)
           
        
      
        
          - 
            
            
            
            
  # for both the <tt>:create</tt> and <tt>:update</tt> methods. To implement,
           
        
      
        
          - 
            
            
            
            
  # you need to wrap the methods you want callbacks on in a block so that the
           
        
      
        
          - 
            
            
            
            
  # callbacks get a chance to fire:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   def create
           
        
      
        
          - 
            
            
            
            
  #     run_callbacks :create do
           
        
      
        
          - 
            
            
            
            
  #       # Your create action methods here
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Then in your class, you can use the +before_create+, +after_create+ and
           
        
      
        
          - 
            
            
            
            
  # +around_create+ methods, just as you would in an Active Record model.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   before_create :action_before_create
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   def action_before_create
           
        
      
        
          - 
            
            
            
            
  #     # Your code here
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # When defining an around callback remember to yield to the block, otherwise
           
        
      
        
          - 
            
            
            
            
  # it won't be executed:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #  around_create :log_status
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #  def log_status
           
        
      
        
          - 
            
            
            
            
  #    puts 'going to call the block...'
           
        
      
        
          - 
            
            
            
            
  #    yield
           
        
      
        
          - 
            
            
            
            
  #    puts 'block successfully called.'
           
        
      
        
          - 
            
            
            
            
  #  end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # You can choose to have only specific callbacks by passing a hash to the
           
        
      
        
          - 
            
            
            
            
  # +define_model_callbacks+ method.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   define_model_callbacks :create, only: [:after, :before]
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Would only create the +after_create+ and +before_create+ callback methods in
           
        
      
        
          - 
            
            
            
            
  # your class.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            1
            
            
            
  module Callbacks
           
        
      
        
          - 
            1
            
            
            
    def self.extended(base) #:nodoc:
           
        
      
        
          - 
            18
            
            
            
      base.class_eval do
           
        
      
        
          - 
            18
            
            
            
        include ActiveSupport::Callbacks
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # define_model_callbacks accepts the same options +define_callbacks+ does,
           
        
      
        
          - 
            
            
            
            
    # in case you want to overwrite a default. Besides that, it also accepts an
           
        
      
        
          - 
            
            
            
            
    # <tt>:only</tt> option, where you can choose if you want all types (before,
           
        
      
        
          - 
            
            
            
            
    # around or after) or just some.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   define_model_callbacks :initializer, only: :after
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Note, the <tt>only: <type></tt> hash will apply to all callbacks defined
           
        
      
        
          - 
            
            
            
            
    # on that method call. To get around this you can call the define_model_callbacks
           
        
      
        
          - 
            
            
            
            
    # method as many times as you need.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   define_model_callbacks :create,  only: :after
           
        
      
        
          - 
            
            
            
            
    #   define_model_callbacks :update,  only: :before
           
        
      
        
          - 
            
            
            
            
    #   define_model_callbacks :destroy, only: :around
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Would create +after_create+, +before_update+ and +around_destroy+ methods
           
        
      
        
          - 
            
            
            
            
    # only.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # You can pass in a class to before_<type>, after_<type> and around_<type>,
           
        
      
        
          - 
            
            
            
            
    # in which case the callback will call that class's <action>_<type> method
           
        
      
        
          - 
            
            
            
            
    # passing the object that the callback is being called on.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class MyModel
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Callbacks
           
        
      
        
          - 
            
            
            
            
    #     define_model_callbacks :create
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     before_create AnotherClass
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class AnotherClass
           
        
      
        
          - 
            
            
            
            
    #     def self.before_create( obj )
           
        
      
        
          - 
            
            
            
            
    #       # obj is the MyModel instance that the callback is being called on
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # NOTE: +method_name+ passed to define_model_callbacks must not end with
           
        
      
        
          - 
            
            
            
            
    # <tt>!</tt>, <tt>?</tt> or <tt>=</tt>.
           
        
      
        
          - 
            1
            
            
            
    def define_model_callbacks(*callbacks)
           
        
      
        
          - 
            7
            
            
            
      options = callbacks.extract_options!
           
        
      
        
          - 
            7
            
            
            
      options = {
           
        
      
        
          - 
            
            
            
            
        skip_after_callbacks_if_terminated: true,
           
        
      
        
          - 
            
            
            
            
        scope: [:kind, :name],
           
        
      
        
          - 
            
            
            
            
        only: [:before, :around, :after]
           
        
      
        
          - 
            
            
            
            
      }.merge!(options)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            7
            
            
            
      types = Array(options.delete(:only))
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            7
            
            
            
      callbacks.each do |callback|
           
        
      
        
          - 
            7
            
            
            
        define_callbacks(callback, options)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            7
            
            
            
        types.each do |type|
           
        
      
        
          - 
            15
            
            
            
          send("_define_#{type}_model_callback", self, callback)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def _define_before_model_callback(klass, callback)
           
        
      
        
          - 
            5
            
            
            
        klass.define_singleton_method("before_#{callback}") do |*args, **options, &block|
           
        
      
        
          - 
            1
            
            
            
          options.assert_valid_keys(:if, :unless, :prepend)
           
        
      
        
          - 
            1
            
            
            
          set_callback(:"#{callback}", :before, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _define_around_model_callback(klass, callback)
           
        
      
        
          - 
            5
            
            
            
        klass.define_singleton_method("around_#{callback}") do |*args, **options, &block|
           
        
      
        
          - 
            1
            
            
            
          options.assert_valid_keys(:if, :unless, :prepend)
           
        
      
        
          - 
            1
            
            
            
          set_callback(:"#{callback}", :around, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _define_after_model_callback(klass, callback)
           
        
      
        
          - 
            5
            
            
            
        klass.define_singleton_method("after_#{callback}") do |*args, **options, &block|
           
        
      
        
          - 
            5
            
            
            
          options.assert_valid_keys(:if, :unless, :prepend)
           
        
      
        
          - 
            5
            
            
            
          options[:prepend] = true
           
        
      
        
          - 
            5
            
            
            
          conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v|
           
        
      
        
          - 
            12
            
            
            
            v != false
           
        
      
        
          - 
            
            
            
            
          }
           
        
      
        
          - 
            5
            
            
            
          options[:if] = Array(options[:if]) << conditional
           
        
      
        
          - 
            5
            
            
            
          set_callback(:"#{callback}", :after, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Conversion
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Handles default conversions: to_model, to_key, to_param, and to_partial_path.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Let's take for example this non-persisted object.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class ContactMessage
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     # ContactMessage are never persisted in the DB
           
        
      
        
          - 
            
            
            
            
  #     def persisted?
           
        
      
        
          - 
            
            
            
            
  #       false
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   cm = ContactMessage.new
           
        
      
        
          - 
            
            
            
            
  #   cm.to_model == cm  # => true
           
        
      
        
          - 
            
            
            
            
  #   cm.to_key          # => nil
           
        
      
        
          - 
            
            
            
            
  #   cm.to_param        # => nil
           
        
      
        
          - 
            
            
            
            
  #   cm.to_partial_path # => "contact_messages/contact_message"
           
        
      
        
          - 
            1
            
            
            
  module Conversion
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # If your object is already designed to implement all of the \Active \Model
           
        
      
        
          - 
            
            
            
            
    # you can use the default <tt>:to_model</tt> implementation, which simply
           
        
      
        
          - 
            
            
            
            
    # returns +self+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.to_model == person # => true
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If your model does not act like an \Active \Model object, then you should
           
        
      
        
          - 
            
            
            
            
    # define <tt>:to_model</tt> yourself returning a proxy object that wraps
           
        
      
        
          - 
            
            
            
            
    # your object with \Active \Model compliant methods.
           
        
      
        
          - 
            1
            
            
            
    def to_model
           
        
      
        
          - 
            42
            
            
            
      self
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns an Array of all key attributes if any of the attributes is set, whether or not
           
        
      
        
          - 
            
            
            
            
    # the object is persisted. Returns +nil+ if there are no key attributes.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :id
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def initialize(id)
           
        
      
        
          - 
            
            
            
            
    #       @id = id
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new(1)
           
        
      
        
          - 
            
            
            
            
    #   person.to_key # => [1]
           
        
      
        
          - 
            1
            
            
            
    def to_key
           
        
      
        
          - 
            7
            
            
            
      key = respond_to?(:id) && id
           
        
      
        
          - 
            7
            
            
            
      key ? [key] : nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a +string+ representing the object's key suitable for use in URLs,
           
        
      
        
          - 
            
            
            
            
    # or +nil+ if <tt>persisted?</tt> is +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :id
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def initialize(id)
           
        
      
        
          - 
            
            
            
            
    #       @id = id
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def persisted?
           
        
      
        
          - 
            
            
            
            
    #       true
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new(1)
           
        
      
        
          - 
            
            
            
            
    #   person.to_param # => "1"
           
        
      
        
          - 
            1
            
            
            
    def to_param
           
        
      
        
          - 
            6
            
            
            
      (persisted? && key = to_key) ? key.join("-") : nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a +string+ identifying the path associated with the object.
           
        
      
        
          - 
            
            
            
            
    # ActionPack uses this to find a suitable partial to represent the object.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.to_partial_path # => "people/person"
           
        
      
        
          - 
            1
            
            
            
    def to_partial_path
           
        
      
        
          - 
            5
            
            
            
      self.class._to_partial_path
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods #:nodoc:
           
        
      
        
          - 
            
            
            
            
      # Provide a class level cache for #to_partial_path. This is an
           
        
      
        
          - 
            
            
            
            
      # internal method and should not be accessed directly.
           
        
      
        
          - 
            1
            
            
            
      def _to_partial_path #:nodoc:
           
        
      
        
          - 
            5
            
            
            
        @_to_partial_path ||= begin
           
        
      
        
          - 
            5
            
            
            
          element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(name))
           
        
      
        
          - 
            5
            
            
            
          collection = ActiveSupport::Inflector.tableize(name)
           
        
      
        
          - 
            5
            
            
            
          "#{collection}/#{element}"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/attribute_mutation_tracker"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Dirty
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides a way to track changes in your object in the same way as
           
        
      
        
          - 
            
            
            
            
  # Active Record does.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # The requirements for implementing ActiveModel::Dirty are:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # * <tt>include ActiveModel::Dirty</tt> in your object.
           
        
      
        
          - 
            
            
            
            
  # * Call <tt>define_attribute_methods</tt> passing each method you want to
           
        
      
        
          - 
            
            
            
            
  #   track.
           
        
      
        
          - 
            
            
            
            
  # * Call <tt>[attr_name]_will_change!</tt> before each change to the tracked
           
        
      
        
          - 
            
            
            
            
  #   attribute.
           
        
      
        
          - 
            
            
            
            
  # * Call <tt>changes_applied</tt> after the changes are persisted.
           
        
      
        
          - 
            
            
            
            
  # * Call <tt>clear_changes_information</tt> when you want to reset the changes
           
        
      
        
          - 
            
            
            
            
  #   information.
           
        
      
        
          - 
            
            
            
            
  # * Call <tt>restore_attributes</tt> when you want to restore previous data.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Dirty
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     define_attribute_methods :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def initialize
           
        
      
        
          - 
            
            
            
            
  #       @name = nil
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def name
           
        
      
        
          - 
            
            
            
            
  #       @name
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def name=(val)
           
        
      
        
          - 
            
            
            
            
  #       name_will_change! unless val == @name
           
        
      
        
          - 
            
            
            
            
  #       @name = val
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def save
           
        
      
        
          - 
            
            
            
            
  #       # do persistence work
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #       changes_applied
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def reload!
           
        
      
        
          - 
            
            
            
            
  #       # get the values from the persistence layer
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #       clear_changes_information
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def rollback!
           
        
      
        
          - 
            
            
            
            
  #       restore_attributes
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A newly instantiated +Person+ object is unchanged:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.changed? # => false
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Change the name:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
  #   person.changed?       # => true
           
        
      
        
          - 
            
            
            
            
  #   person.name_changed?  # => true
           
        
      
        
          - 
            
            
            
            
  #   person.name_changed?(from: nil, to: "Bob") # => true
           
        
      
        
          - 
            
            
            
            
  #   person.name_was       # => nil
           
        
      
        
          - 
            
            
            
            
  #   person.name_change    # => [nil, "Bob"]
           
        
      
        
          - 
            
            
            
            
  #   person.name = 'Bill'
           
        
      
        
          - 
            
            
            
            
  #   person.name_change    # => [nil, "Bill"]
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Save the changes:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.save
           
        
      
        
          - 
            
            
            
            
  #   person.changed?      # => false
           
        
      
        
          - 
            
            
            
            
  #   person.name_changed? # => false
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Reset the changes:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.previous_changes         # => {"name" => [nil, "Bill"]}
           
        
      
        
          - 
            
            
            
            
  #   person.name_previously_changed? # => true
           
        
      
        
          - 
            
            
            
            
  #   person.name_previously_changed?(from: nil, to: "Bill") # => true
           
        
      
        
          - 
            
            
            
            
  #   person.name_previous_change     # => [nil, "Bill"]
           
        
      
        
          - 
            
            
            
            
  #   person.name_previously_was      # => nil
           
        
      
        
          - 
            
            
            
            
  #   person.reload!
           
        
      
        
          - 
            
            
            
            
  #   person.previous_changes         # => {}
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Rollback the changes:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name = "Uncle Bob"
           
        
      
        
          - 
            
            
            
            
  #   person.rollback!
           
        
      
        
          - 
            
            
            
            
  #   person.name          # => "Bill"
           
        
      
        
          - 
            
            
            
            
  #   person.name_changed? # => false
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Assigning the same value leaves the attribute unchanged:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name = 'Bill'
           
        
      
        
          - 
            
            
            
            
  #   person.name_changed? # => false
           
        
      
        
          - 
            
            
            
            
  #   person.name_change   # => nil
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Which attributes have changed?
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name = 'Bob'
           
        
      
        
          - 
            
            
            
            
  #   person.changed # => ["name"]
           
        
      
        
          - 
            
            
            
            
  #   person.changes # => {"name" => ["Bill", "Bob"]}
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # If an attribute is modified in-place then make use of
           
        
      
        
          - 
            
            
            
            
  # <tt>[attribute_name]_will_change!</tt> to mark that the attribute is changing.
           
        
      
        
          - 
            
            
            
            
  # Otherwise \Active \Model can't track changes to in-place attributes. Note
           
        
      
        
          - 
            
            
            
            
  # that Active Record can detect in-place modifications automatically. You do
           
        
      
        
          - 
            
            
            
            
  # not need to call <tt>[attribute_name]_will_change!</tt> on Active Record models.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name_will_change!
           
        
      
        
          - 
            
            
            
            
  #   person.name_change # => ["Bill", "Bill"]
           
        
      
        
          - 
            
            
            
            
  #   person.name << 'y'
           
        
      
        
          - 
            
            
            
            
  #   person.name_change # => ["Bill", "Billy"]
           
        
      
        
          - 
            1
            
            
            
  module Dirty
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::AttributeMethods
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    included do
           
        
      
        
          - 
            2
            
            
            
      attribute_method_suffix "_changed?", "_change", "_will_change!", "_was"
           
        
      
        
          - 
            2
            
            
            
      attribute_method_suffix "_previously_changed?", "_previous_change", "_previously_was"
           
        
      
        
          - 
            2
            
            
            
      attribute_method_affix prefix: "restore_", suffix: "!"
           
        
      
        
          - 
            2
            
            
            
      attribute_method_affix prefix: "clear_", suffix: "_change"
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(other) # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      super
           
        
      
        
          - 
            1
            
            
            
      if self.class.respond_to?(:_default_attributes)
           
        
      
        
          - 
            
            
            
            
        @attributes = self.class._default_attributes.map do |attr|
           
        
      
        
          - 
            
            
            
            
          attr.with_value_from_user(@attributes.fetch_value(attr.name))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            1
            
            
            
      @mutations_from_database = nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Clears dirty data and moves +changes+ to +previous_changes+ and
           
        
      
        
          - 
            
            
            
            
    # +mutations_from_database+ to +mutations_before_last_save+ respectively.
           
        
      
        
          - 
            1
            
            
            
    def changes_applied
           
        
      
        
          - 
            25
            
            
            
      unless defined?(@attributes)
           
        
      
        
          - 
            12
            
            
            
        mutations_from_database.finalize_changes
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            25
            
            
            
      @mutations_before_last_save = mutations_from_database
           
        
      
        
          - 
            25
            
            
            
      forget_attribute_assignments
           
        
      
        
          - 
            25
            
            
            
      @mutations_from_database = nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns +true+ if any of the attributes has unsaved changes, +false+ otherwise.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.changed? # => false
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'bob'
           
        
      
        
          - 
            
            
            
            
    #   person.changed? # => true
           
        
      
        
          - 
            1
            
            
            
    def changed?
           
        
      
        
          - 
            18
            
            
            
      mutations_from_database.any_changes?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns an array with the name of the attributes with unsaved changes.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.changed # => []
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'bob'
           
        
      
        
          - 
            
            
            
            
    #   person.changed # => ["name"]
           
        
      
        
          - 
            1
            
            
            
    def changed
           
        
      
        
          - 
            6
            
            
            
      mutations_from_database.changed_attribute_names
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Dispatch target for <tt>*_changed?</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
    def attribute_changed?(attr_name, **options) # :nodoc:
           
        
      
        
          - 
            48
            
            
            
      mutations_from_database.changed?(attr_name.to_s, **options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Dispatch target for <tt>*_was</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
    def attribute_was(attr_name) # :nodoc:
           
        
      
        
          - 
            10
            
            
            
      mutations_from_database.original_value(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Dispatch target for <tt>*_previously_changed?</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
    def attribute_previously_changed?(attr_name, **options) # :nodoc:
           
        
      
        
          - 
            8
            
            
            
      mutations_before_last_save.changed?(attr_name.to_s, **options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Dispatch target for <tt>*_previously_was</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
    def attribute_previously_was(attr_name) # :nodoc:
           
        
      
        
          - 
            
            
            
            
      mutations_before_last_save.original_value(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Restore all previous data of the provided attributes.
           
        
      
        
          - 
            1
            
            
            
    def restore_attributes(attr_names = changed)
           
        
      
        
          - 
            10
            
            
            
      attr_names.each { |attr_name| restore_attribute!(attr_name) }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Clears all dirty data: current changes and previous changes.
           
        
      
        
          - 
            1
            
            
            
    def clear_changes_information
           
        
      
        
          - 
            2
            
            
            
      @mutations_before_last_save = nil
           
        
      
        
          - 
            2
            
            
            
      forget_attribute_assignments
           
        
      
        
          - 
            2
            
            
            
      @mutations_from_database = nil
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def clear_attribute_changes(attr_names)
           
        
      
        
          - 
            
            
            
            
      attr_names.each do |attr_name|
           
        
      
        
          - 
            
            
            
            
        clear_attribute_change(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a hash of the attributes with unsaved changes indicating their original
           
        
      
        
          - 
            
            
            
            
    # values like <tt>attr => original value</tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.name # => "bob"
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'robert'
           
        
      
        
          - 
            
            
            
            
    #   person.changed_attributes # => {"name" => "bob"}
           
        
      
        
          - 
            1
            
            
            
    def changed_attributes
           
        
      
        
          - 
            10
            
            
            
      mutations_from_database.changed_values
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a hash of changed attributes indicating their original
           
        
      
        
          - 
            
            
            
            
    # and new values like <tt>attr => [original value, new value]</tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.changes # => {}
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'bob'
           
        
      
        
          - 
            
            
            
            
    #   person.changes # => { "name" => ["bill", "bob"] }
           
        
      
        
          - 
            1
            
            
            
    def changes
           
        
      
        
          - 
            9
            
            
            
      mutations_from_database.changes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a hash of attributes that were changed before the model was saved.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.name # => "bob"
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'robert'
           
        
      
        
          - 
            
            
            
            
    #   person.save
           
        
      
        
          - 
            
            
            
            
    #   person.previous_changes # => {"name" => ["bob", "robert"]}
           
        
      
        
          - 
            1
            
            
            
    def previous_changes
           
        
      
        
          - 
            8
            
            
            
      mutations_before_last_save.changes
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def attribute_changed_in_place?(attr_name) # :nodoc:
           
        
      
        
          - 
            
            
            
            
      mutations_from_database.changed_in_place?(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def clear_attribute_change(attr_name)
           
        
      
        
          - 
            8
            
            
            
        mutations_from_database.forget_change(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def mutations_from_database
           
        
      
        
          - 
            193
            
            
            
        @mutations_from_database ||= if defined?(@attributes)
           
        
      
        
          - 
            31
            
            
            
          ActiveModel::AttributeMutationTracker.new(@attributes)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            30
            
            
            
          ActiveModel::ForcedMutationTracker.new(self)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def forget_attribute_assignments
           
        
      
        
          - 
            27
            
            
            
        @attributes = @attributes.map(&:forgetting_assignment) if defined?(@attributes)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def mutations_before_last_save
           
        
      
        
          - 
            18
            
            
            
        @mutations_before_last_save ||= ActiveModel::NullMutationTracker.instance
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Dispatch target for <tt>*_change</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
      def attribute_change(attr_name)
           
        
      
        
          - 
            3
            
            
            
        mutations_from_database.change_to_attribute(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Dispatch target for <tt>*_previous_change</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
      def attribute_previous_change(attr_name)
           
        
      
        
          - 
            2
            
            
            
        mutations_before_last_save.change_to_attribute(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Dispatch target for <tt>*_will_change!</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
      def attribute_will_change!(attr_name)
           
        
      
        
          - 
            44
            
            
            
        mutations_from_database.force_change(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Dispatch target for <tt>restore_*!</tt> attribute methods.
           
        
      
        
          - 
            1
            
            
            
      def restore_attribute!(attr_name)
           
        
      
        
          - 
            8
            
            
            
        attr_name = attr_name.to_s
           
        
      
        
          - 
            8
            
            
            
        if attribute_changed?(attr_name)
           
        
      
        
          - 
            8
            
            
            
          __send__("#{attr_name}=", attribute_was(attr_name))
           
        
      
        
          - 
            8
            
            
            
          clear_attribute_change(attr_name)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/class/attribute"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Error
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Represents one single error
           
        
      
        
          - 
            1
            
            
            
  class Error
           
        
      
        
          - 
            1
            
            
            
    CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
           
        
      
        
          - 
            1
            
            
            
    MESSAGE_OPTIONS = [:message]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    class_attribute :i18n_customize_full_message, default: false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def self.full_message(attribute, message, base_class) # :nodoc:
           
        
      
        
          - 
            60
            
            
            
      return message if attribute == :base
           
        
      
        
          - 
            56
            
            
            
      attribute = attribute.to_s
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            56
            
            
            
      if i18n_customize_full_message && base_class.respond_to?(:i18n_scope)
           
        
      
        
          - 
            18
            
            
            
        attribute = attribute.remove(/\[\d+\]/)
           
        
      
        
          - 
            18
            
            
            
        parts = attribute.split(".")
           
        
      
        
          - 
            18
            
            
            
        attribute_name = parts.pop
           
        
      
        
          - 
            18
            
            
            
        namespace = parts.join("/") unless parts.empty?
           
        
      
        
          - 
            18
            
            
            
        attributes_scope = "#{base_class.i18n_scope}.errors.models"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            18
            
            
            
        if namespace
           
        
      
        
          - 
            11
            
            
            
          defaults = base_class.lookup_ancestors.map do |klass|
           
        
      
        
          - 
            22
            
            
            
            [
           
        
      
        
          - 
            
            
            
            
              :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.attributes.#{attribute_name}.format",
           
        
      
        
          - 
            
            
            
            
              :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.format",
           
        
      
        
          - 
            
            
            
            
            ]
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            7
            
            
            
          defaults = base_class.lookup_ancestors.map do |klass|
           
        
      
        
          - 
            14
            
            
            
            [
           
        
      
        
          - 
            
            
            
            
              :"#{attributes_scope}.#{klass.model_name.i18n_key}.attributes.#{attribute_name}.format",
           
        
      
        
          - 
            
            
            
            
              :"#{attributes_scope}.#{klass.model_name.i18n_key}.format",
           
        
      
        
          - 
            
            
            
            
            ]
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            18
            
            
            
        defaults.flatten!
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            38
            
            
            
        defaults = []
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            56
            
            
            
      defaults << :"errors.format"
           
        
      
        
          - 
            56
            
            
            
      defaults << "%{attribute} %{message}"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            56
            
            
            
      attr_name = attribute.tr(".", "_").humanize
           
        
      
        
          - 
            56
            
            
            
      attr_name = base_class.human_attribute_name(attribute, default: attr_name)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            56
            
            
            
      I18n.t(defaults.shift,
           
        
      
        
          - 
            
            
            
            
        default:  defaults,
           
        
      
        
          - 
            
            
            
            
        attribute: attr_name,
           
        
      
        
          - 
            
            
            
            
        message:   message)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def self.generate_message(attribute, type, base, options) # :nodoc:
           
        
      
        
          - 
            559
            
            
            
      type = options.delete(:message) if options[:message].is_a?(Symbol)
           
        
      
        
          - 
            559
            
            
            
      value = (attribute != :base ? base.send(:read_attribute_for_validation, attribute) : nil)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            559
            
            
            
      options = {
           
        
      
        
          - 
            
            
            
            
        model: base.model_name.human,
           
        
      
        
          - 
            
            
            
            
        attribute: base.class.human_attribute_name(attribute),
           
        
      
        
          - 
            
            
            
            
        value: value,
           
        
      
        
          - 
            
            
            
            
        object: base
           
        
      
        
          - 
            
            
            
            
      }.merge!(options)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            559
            
            
            
      if base.class.respond_to?(:i18n_scope)
           
        
      
        
          - 
            513
            
            
            
        i18n_scope = base.class.i18n_scope.to_s
           
        
      
        
          - 
            513
            
            
            
        attribute = attribute.to_s.remove(/\[\d+\]/)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            513
            
            
            
        defaults = base.class.lookup_ancestors.flat_map do |klass|
           
        
      
        
          - 
            564
            
            
            
          [ :"#{i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
           
        
      
        
          - 
            
            
            
            
            :"#{i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ]
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            513
            
            
            
        defaults << :"#{i18n_scope}.errors.messages.#{type}"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        catch(:exception) do
           
        
      
        
          - 
            433
            
            
            
          translation = I18n.translate(defaults.first, **options.merge(default: defaults.drop(1), throw: true))
           
        
      
        
          - 
            29
            
            
            
          return translation unless translation.nil?
           
        
      
        
          - 
            513
            
            
            
        end unless options[:message]
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            46
            
            
            
        defaults = []
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            530
            
            
            
      defaults << :"errors.attributes.#{attribute}.#{type}"
           
        
      
        
          - 
            530
            
            
            
      defaults << :"errors.messages.#{type}"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            530
            
            
            
      key = defaults.shift
           
        
      
        
          - 
            530
            
            
            
      defaults = options.delete(:message) if options[:message]
           
        
      
        
          - 
            530
            
            
            
      options[:default] = defaults
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            530
            
            
            
      I18n.translate(key, **options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(base, attribute, type = :invalid, **options)
           
        
      
        
          - 
            704
            
            
            
      @base = base
           
        
      
        
          - 
            704
            
            
            
      @attribute = attribute
           
        
      
        
          - 
            704
            
            
            
      @raw_type = type
           
        
      
        
          - 
            704
            
            
            
      @type = type || :invalid
           
        
      
        
          - 
            704
            
            
            
      @options = options
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(other) # :nodoc:
           
        
      
        
          - 
            4
            
            
            
      @attribute = @attribute.dup
           
        
      
        
          - 
            4
            
            
            
      @raw_type = @raw_type.dup
           
        
      
        
          - 
            4
            
            
            
      @type = @type.dup
           
        
      
        
          - 
            4
            
            
            
      @options = @options.deep_dup
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # The object which the error belongs to
           
        
      
        
          - 
            1
            
            
            
    attr_reader :base
           
        
      
        
          - 
            
            
            
            
    # The attribute of +base+ which the error belongs to
           
        
      
        
          - 
            1
            
            
            
    attr_reader :attribute
           
        
      
        
          - 
            
            
            
            
    # The type of error, defaults to `:invalid` unless specified
           
        
      
        
          - 
            1
            
            
            
    attr_reader :type
           
        
      
        
          - 
            
            
            
            
    # The raw value provided as the second parameter when calling `errors#add`
           
        
      
        
          - 
            1
            
            
            
    attr_reader :raw_type
           
        
      
        
          - 
            
            
            
            
    # The options provided when calling `errors#add`
           
        
      
        
          - 
            1
            
            
            
    attr_reader :options
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the error message.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
           
        
      
        
          - 
            
            
            
            
    #   error.message
           
        
      
        
          - 
            
            
            
            
    #   # => "is too short (minimum is 5 characters)"
           
        
      
        
          - 
            1
            
            
            
    def message
           
        
      
        
          - 
            705
            
            
            
      case raw_type
           
        
      
        
          - 
            
            
            
            
      when Symbol
           
        
      
        
          - 
            600
            
            
            
        self.class.generate_message(attribute, raw_type, @base, options.except(*CALLBACKS_OPTIONS))
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            105
            
            
            
        raw_type
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the error detail.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
           
        
      
        
          - 
            
            
            
            
    #   error.detail
           
        
      
        
          - 
            
            
            
            
    #   # => { error: :too_short, count: 5 }
           
        
      
        
          - 
            1
            
            
            
    def detail
           
        
      
        
          - 
            20
            
            
            
      { error: raw_type }.merge(options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the full error message.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
           
        
      
        
          - 
            
            
            
            
    #   error.full_message
           
        
      
        
          - 
            
            
            
            
    #   # => "Name is too short (minimum is 5 characters)"
           
        
      
        
          - 
            1
            
            
            
    def full_message
           
        
      
        
          - 
            37
            
            
            
      self.class.full_message(attribute, message, @base.class)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # See if error matches provided +attribute+, +type+ and +options+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Omitted params are not checked for a match.
           
        
      
        
          - 
            1
            
            
            
    def match?(attribute, type = nil, **options)
           
        
      
        
          - 
            650
            
            
            
      if @attribute != attribute || (type && @type != type)
           
        
      
        
          - 
            72
            
            
            
        return false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            578
            
            
            
      options.each do |key, value|
           
        
      
        
          - 
            4
            
            
            
        if @options[key] != value
           
        
      
        
          - 
            2
            
            
            
          return false
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            576
            
            
            
      true
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # See if error matches provided +attribute+, +type+ and +options+ exactly.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # All params must be equal to Error's own attributes to be considered a
           
        
      
        
          - 
            
            
            
            
    # strict match.
           
        
      
        
          - 
            1
            
            
            
    def strict_match?(attribute, type, **options)
           
        
      
        
          - 
            18
            
            
            
      return false unless match?(attribute, type)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            15
            
            
            
      options == @options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def ==(other) # :nodoc:
           
        
      
        
          - 
            7
            
            
            
      other.is_a?(self.class) && attributes_for_hash == other.attributes_for_hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    alias eql? ==
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def hash # :nodoc:
           
        
      
        
          - 
            
            
            
            
      attributes_for_hash.hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def inspect # :nodoc:
           
        
      
        
          - 
            
            
            
            
      "#<#{self.class.name} attribute=#{@attribute}, type=#{@type}, options=#{@options.inspect}>"
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    protected
           
        
      
        
          - 
            1
            
            
            
      def attributes_for_hash
           
        
      
        
          - 
            12
            
            
            
        [@base, @attribute, @raw_type, @options.except(*CALLBACKS_OPTIONS)]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/array/conversions"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/string/inflections"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/object/deep_dup"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/string/filters"
           
        
      
        
          - 
            1
            
            
            
require "active_model/error"
           
        
      
        
          - 
            1
            
            
            
require "active_model/nested_error"
           
        
      
        
          - 
            1
            
            
            
require "forwardable"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Errors
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides error related functionalities you can include in your object
           
        
      
        
          - 
            
            
            
            
  # for handling error messages and interacting with Action View helpers.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     # Required dependency for ActiveModel::Errors
           
        
      
        
          - 
            
            
            
            
  #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def initialize
           
        
      
        
          - 
            
            
            
            
  #       @errors = ActiveModel::Errors.new(self)
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
  #     attr_reader   :errors
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def validate!
           
        
      
        
          - 
            
            
            
            
  #       errors.add(:name, :blank, message: "cannot be nil") if name.nil?
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     # The following methods are needed to be minimally implemented
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def read_attribute_for_validation(attr)
           
        
      
        
          - 
            
            
            
            
  #       send(attr)
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def self.human_attribute_name(attr, options = {})
           
        
      
        
          - 
            
            
            
            
  #       attr
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def self.lookup_ancestors
           
        
      
        
          - 
            
            
            
            
  #       [self]
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # The last three methods are required in your object for +Errors+ to be
           
        
      
        
          - 
            
            
            
            
  # able to generate error messages correctly and also handle multiple
           
        
      
        
          - 
            
            
            
            
  # languages. Of course, if you extend your object with <tt>ActiveModel::Translation</tt>
           
        
      
        
          - 
            
            
            
            
  # you will not need to implement the last two. Likewise, using
           
        
      
        
          - 
            
            
            
            
  # <tt>ActiveModel::Validations</tt> will handle the validation related methods
           
        
      
        
          - 
            
            
            
            
  # for you.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # The above allows you to do:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.validate!            # => ["cannot be nil"]
           
        
      
        
          - 
            
            
            
            
  #   person.errors.full_messages # => ["name cannot be nil"]
           
        
      
        
          - 
            
            
            
            
  #   # etc..
           
        
      
        
          - 
            1
            
            
            
  class Errors
           
        
      
        
          - 
            1
            
            
            
    include Enumerable
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    extend Forwardable
           
        
      
        
          - 
            1
            
            
            
    def_delegators :@errors, :size, :clear, :blank?, :empty?, :uniq!, :any?
           
        
      
        
          - 
            
            
            
            
    # TODO: forward all enumerable methods after `each` deprecation is removed.
           
        
      
        
          - 
            1
            
            
            
    def_delegators :@errors, :count
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    LEGACY_ATTRIBUTES = [:messages, :details].freeze
           
        
      
        
          - 
            1
            
            
            
    private_constant :LEGACY_ATTRIBUTES
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # The actual array of +Error+ objects
           
        
      
        
          - 
            
            
            
            
    # This method is aliased to <tt>objects</tt>.
           
        
      
        
          - 
            1
            
            
            
    attr_reader :errors
           
        
      
        
          - 
            1
            
            
            
    alias :objects :errors
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Pass in the instance of the object that is using the errors object.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     def initialize
           
        
      
        
          - 
            
            
            
            
    #       @errors = ActiveModel::Errors.new(self)
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            1
            
            
            
    def initialize(base)
           
        
      
        
          - 
            650
            
            
            
      @base = base
           
        
      
        
          - 
            650
            
            
            
      @errors = []
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(other) # :nodoc:
           
        
      
        
          - 
            2
            
            
            
      @errors = other.errors.deep_dup
           
        
      
        
          - 
            2
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Copies the errors from <tt>other</tt>.
           
        
      
        
          - 
            
            
            
            
    # For copying errors but keep <tt>@base</tt> as is.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # other - The ActiveModel::Errors instance.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Examples
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.copy!(other)
           
        
      
        
          - 
            1
            
            
            
    def copy!(other) # :nodoc:
           
        
      
        
          - 
            2
            
            
            
      @errors = other.errors.deep_dup
           
        
      
        
          - 
            2
            
            
            
      @errors.each { |error|
           
        
      
        
          - 
            2
            
            
            
        error.instance_variable_set(:@base, @base)
           
        
      
        
          - 
            
            
            
            
      }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Imports one error
           
        
      
        
          - 
            
            
            
            
    # Imported errors are wrapped as a NestedError,
           
        
      
        
          - 
            
            
            
            
    # providing access to original error object.
           
        
      
        
          - 
            
            
            
            
    # If attribute or type needs to be overridden, use `override_options`.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # override_options - Hash
           
        
      
        
          - 
            
            
            
            
    # @option override_options [Symbol] :attribute Override the attribute the error belongs to
           
        
      
        
          - 
            
            
            
            
    # @option override_options [Symbol] :type Override type of the error.
           
        
      
        
          - 
            1
            
            
            
    def import(error, override_options = {})
           
        
      
        
          - 
            3
            
            
            
      [:attribute, :type].each do |key|
           
        
      
        
          - 
            6
            
            
            
        if override_options.key?(key)
           
        
      
        
          - 
            1
            
            
            
          override_options[key] = override_options[key].to_sym
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            3
            
            
            
      @errors.append(NestedError.new(@base, error, override_options))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Merges the errors from <tt>other</tt>,
           
        
      
        
          - 
            
            
            
            
    # each <tt>Error</tt> wrapped as <tt>NestedError</tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # other - The ActiveModel::Errors instance.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Examples
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.merge!(other)
           
        
      
        
          - 
            1
            
            
            
    def merge!(other)
           
        
      
        
          - 
            2
            
            
            
      other.errors.each { |error|
           
        
      
        
          - 
            2
            
            
            
        import(error)
           
        
      
        
          - 
            
            
            
            
      }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Removes all errors except the given keys. Returns a hash containing the removed errors.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.keys                  # => [:name, :age, :gender, :city]
           
        
      
        
          - 
            
            
            
            
    #   person.errors.slice!(:age, :gender) # => { :name=>["cannot be nil"], :city=>["cannot be nil"] }
           
        
      
        
          - 
            
            
            
            
    #   person.errors.keys                  # => [:age, :gender]
           
        
      
        
          - 
            1
            
            
            
    def slice!(*keys)
           
        
      
        
          - 
            2
            
            
            
      deprecation_removal_warning(:slice!)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      keys = keys.map(&:to_sym)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      results = messages.dup.slice!(*keys)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      @errors.keep_if do |error|
           
        
      
        
          - 
            8
            
            
            
        keys.include?(error.attribute)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      results
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Search for errors matching +attribute+, +type+ or +options+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Only supplied params will be matched.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.where(:name) # => all name errors.
           
        
      
        
          - 
            
            
            
            
    #   person.errors.where(:name, :too_short) # => all name errors being too short
           
        
      
        
          - 
            
            
            
            
    #   person.errors.where(:name, :too_short, minimum: 2) # => all name errors being too short and minimum is 2
           
        
      
        
          - 
            1
            
            
            
    def where(attribute, type = nil, **options)
           
        
      
        
          - 
            790
            
            
            
      attribute, type, options = normalize_arguments(attribute, type, **options)
           
        
      
        
          - 
            790
            
            
            
      @errors.select { |error|
           
        
      
        
          - 
            616
            
            
            
        error.match?(attribute, type, **options)
           
        
      
        
          - 
            
            
            
            
      }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns +true+ if the error messages include an error for the given key
           
        
      
        
          - 
            
            
            
            
    # +attribute+, +false+ otherwise.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages        # => {:name=>["cannot be nil"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.include?(:name) # => true
           
        
      
        
          - 
            
            
            
            
    #   person.errors.include?(:age)  # => false
           
        
      
        
          - 
            1
            
            
            
    def include?(attribute)
           
        
      
        
          - 
            10
            
            
            
      @errors.any? { |error|
           
        
      
        
          - 
            6
            
            
            
        error.match?(attribute.to_sym)
           
        
      
        
          - 
            
            
            
            
      }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    alias :has_key? :include?
           
        
      
        
          - 
            1
            
            
            
    alias :key? :include?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Delete messages for +key+. Returns the deleted messages.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors[:name]        # => ["cannot be nil"]
           
        
      
        
          - 
            
            
            
            
    #   person.errors.delete(:name) # => ["cannot be nil"]
           
        
      
        
          - 
            
            
            
            
    #   person.errors[:name]        # => []
           
        
      
        
          - 
            1
            
            
            
    def delete(attribute, type = nil, **options)
           
        
      
        
          - 
            10
            
            
            
      attribute, type, options = normalize_arguments(attribute, type, **options)
           
        
      
        
          - 
            10
            
            
            
      matches = where(attribute, type, **options)
           
        
      
        
          - 
            10
            
            
            
      matches.each do |error|
           
        
      
        
          - 
            6
            
            
            
        @errors.delete(error)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            10
            
            
            
      matches.map(&:message).presence
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # When passed a symbol or a name of a method, returns an array of errors
           
        
      
        
          - 
            
            
            
            
    # for the method.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors[:name]  # => ["cannot be nil"]
           
        
      
        
          - 
            
            
            
            
    #   person.errors['name'] # => ["cannot be nil"]
           
        
      
        
          - 
            1
            
            
            
    def [](attribute)
           
        
      
        
          - 
            747
            
            
            
      DeprecationHandlingMessageArray.new(messages_for(attribute), self, attribute)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Iterates through each error object.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :too_short, count: 2)
           
        
      
        
          - 
            
            
            
            
    #   person.errors.each do |error|
           
        
      
        
          - 
            
            
            
            
    #     # Will yield <#ActiveModel::Error attribute=name, type=too_short,
           
        
      
        
          - 
            
            
            
            
    #                                       options={:count=>3}>
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # To be backward compatible with past deprecated hash-like behavior,
           
        
      
        
          - 
            
            
            
            
    # when block accepts two parameters instead of one, it
           
        
      
        
          - 
            
            
            
            
    # iterates through each error key, value pair in the error messages hash.
           
        
      
        
          - 
            
            
            
            
    # Yields the attribute and the error for that attribute. If the attribute
           
        
      
        
          - 
            
            
            
            
    # has more than one error message, yields once for each error message.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :blank, message: "can't be blank")
           
        
      
        
          - 
            
            
            
            
    #   person.errors.each do |attribute, message|
           
        
      
        
          - 
            
            
            
            
    #     # Will yield :name and "can't be blank"
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :not_specified, message: "must be specified")
           
        
      
        
          - 
            
            
            
            
    #   person.errors.each do |attribute, message|
           
        
      
        
          - 
            
            
            
            
    #     # Will yield :name and "can't be blank"
           
        
      
        
          - 
            
            
            
            
    #     # then yield :name and "must be specified"
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            1
            
            
            
    def each(&block)
           
        
      
        
          - 
            4
            
            
            
      if block.arity <= 1
           
        
      
        
          - 
            3
            
            
            
        @errors.each(&block)
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            1
            
            
            
        ActiveSupport::Deprecation.warn(<<~MSG)
           
        
      
        
          - 
            
            
            
            
          Enumerating ActiveModel::Errors as a hash has been deprecated.
           
        
      
        
          - 
            
            
            
            
          In Rails 6.1, `errors` is an array of Error objects,
           
        
      
        
          - 
            
            
            
            
          therefore it should be accessed by a block with a single block
           
        
      
        
          - 
            
            
            
            
          parameter like this:
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          person.errors.each do |error|
           
        
      
        
          - 
            
            
            
            
            attribute = error.attribute
           
        
      
        
          - 
            
            
            
            
            message = error.message
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          You are passing a block expecting two parameters,
           
        
      
        
          - 
            
            
            
            
          so the old hash behavior is simulated. As this is deprecated,
           
        
      
        
          - 
            
            
            
            
          this will result in an ArgumentError in Rails 6.2.
           
        
      
        
          - 
            
            
            
            
        MSG
           
        
      
        
          - 
            
            
            
            
        @errors.
           
        
      
        
          - 
            1
            
            
            
          sort { |a, b| a.attribute <=> b.attribute }.
           
        
      
        
          - 
            3
            
            
            
          each { |error| yield error.attribute, error.message }
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all message values.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.values   # => [["cannot be nil", "must be specified"]]
           
        
      
        
          - 
            1
            
            
            
    def values
           
        
      
        
          - 
            2
            
            
            
      deprecation_removal_warning(:values, "errors.map { |error| error.message }")
           
        
      
        
          - 
            2
            
            
            
      @errors.map(&:message).freeze
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all message keys.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.keys     # => [:name]
           
        
      
        
          - 
            1
            
            
            
    def keys
           
        
      
        
          - 
            7
            
            
            
      deprecation_removal_warning(:keys, "errors.attribute_names")
           
        
      
        
          - 
            7
            
            
            
      keys = @errors.map(&:attribute)
           
        
      
        
          - 
            7
            
            
            
      keys.uniq!
           
        
      
        
          - 
            7
            
            
            
      keys.freeze
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all error attribute names
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages        # => {:name=>["cannot be nil", "must be specified"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.attribute_names # => [:name]
           
        
      
        
          - 
            1
            
            
            
    def attribute_names
           
        
      
        
          - 
            3
            
            
            
      @errors.map(&:attribute).uniq.freeze
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns an xml formatted representation of the Errors hash.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :blank, message: "can't be blank")
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :not_specified, message: "must be specified")
           
        
      
        
          - 
            
            
            
            
    #   person.errors.to_xml
           
        
      
        
          - 
            
            
            
            
    #   # =>
           
        
      
        
          - 
            
            
            
            
    #   #  <?xml version=\"1.0\" encoding=\"UTF-8\"?>
           
        
      
        
          - 
            
            
            
            
    #   #  <errors>
           
        
      
        
          - 
            
            
            
            
    #   #    <error>name can't be blank</error>
           
        
      
        
          - 
            
            
            
            
    #   #    <error>name must be specified</error>
           
        
      
        
          - 
            
            
            
            
    #   #  </errors>
           
        
      
        
          - 
            1
            
            
            
    def to_xml(options = {})
           
        
      
        
          - 
            1
            
            
            
      deprecation_removal_warning(:to_xml)
           
        
      
        
          - 
            1
            
            
            
      to_a.to_xml({ root: "errors", skip_types: true }.merge!(options))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a Hash that can be used as the JSON representation for this
           
        
      
        
          - 
            
            
            
            
    # object. You can pass the <tt>:full_messages</tt> option. This determines
           
        
      
        
          - 
            
            
            
            
    # if the json object should contain full messages or not (false by default).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.as_json                      # => {:name=>["cannot be nil"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.as_json(full_messages: true) # => {:name=>["name cannot be nil"]}
           
        
      
        
          - 
            1
            
            
            
    def as_json(options = nil)
           
        
      
        
          - 
            5
            
            
            
      to_hash(options && options[:full_messages])
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a Hash of attributes with their error messages. If +full_messages+
           
        
      
        
          - 
            
            
            
            
    # is +true+, it will contain full messages (see +full_message+).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.to_hash       # => {:name=>["cannot be nil"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
           
        
      
        
          - 
            1
            
            
            
    def to_hash(full_messages = false)
           
        
      
        
          - 
            114
            
            
            
      hash = {}
           
        
      
        
          - 
            114
            
            
            
      message_method = full_messages ? :full_message : :message
           
        
      
        
          - 
            114
            
            
            
      group_by_attribute.each do |attribute, errors|
           
        
      
        
          - 
            108
            
            
            
        hash[attribute] = errors.map(&message_method)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            114
            
            
            
      hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def to_h
           
        
      
        
          - 
            1
            
            
            
      ActiveSupport::Deprecation.warn(<<~EOM)
           
        
      
        
          - 
            
            
            
            
        ActiveModel::Errors#to_h is deprecated and will be removed in Rails 6.2.
           
        
      
        
          - 
            
            
            
            
        Please use `ActiveModel::Errors.to_hash` instead. The values in the hash
           
        
      
        
          - 
            
            
            
            
        returned by `ActiveModel::Errors.to_hash` is an array of error messages.
           
        
      
        
          - 
            
            
            
            
      EOM
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      to_hash.transform_values { |values| values.last }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a Hash of attributes with an array of their error messages.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Updating this hash would still update errors state for backward
           
        
      
        
          - 
            
            
            
            
    # compatibility, but this behavior is deprecated.
           
        
      
        
          - 
            1
            
            
            
    def messages
           
        
      
        
          - 
            102
            
            
            
      DeprecationHandlingMessageHash.new(self)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a Hash of attributes with an array of their error details.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Updating this hash would still update errors state for backward
           
        
      
        
          - 
            
            
            
            
    # compatibility, but this behavior is deprecated.
           
        
      
        
          - 
            1
            
            
            
    def details
           
        
      
        
          - 
            20
            
            
            
      hash = {}
           
        
      
        
          - 
            20
            
            
            
      group_by_attribute.each do |attribute, errors|
           
        
      
        
          - 
            18
            
            
            
        hash[attribute] = errors.map(&:detail)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            20
            
            
            
      DeprecationHandlingDetailsHash.new(hash)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a Hash of attributes with an array of their Error objects.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.group_by_attribute
           
        
      
        
          - 
            
            
            
            
    #   # => {:name=>[<#ActiveModel::Error>, <#ActiveModel::Error>]}
           
        
      
        
          - 
            1
            
            
            
    def group_by_attribute
           
        
      
        
          - 
            135
            
            
            
      @errors.group_by(&:attribute)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Adds a new error of +type+ on +attribute+.
           
        
      
        
          - 
            
            
            
            
    # More than one error can be added to the same +attribute+.
           
        
      
        
          - 
            
            
            
            
    # If no +type+ is supplied, <tt>:invalid</tt> is assumed.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name)
           
        
      
        
          - 
            
            
            
            
    #   # Adds <#ActiveModel::Error attribute=name, type=invalid>
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :not_implemented, message: "must be implemented")
           
        
      
        
          - 
            
            
            
            
    #   # Adds <#ActiveModel::Error attribute=name, type=not_implemented,
           
        
      
        
          - 
            
            
            
            
    #                               options={:message=>"must be implemented"}>
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages
           
        
      
        
          - 
            
            
            
            
    #   # => {:name=>["is invalid", "must be implemented"]}
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If +type+ is a string, it will be used as error message.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If +type+ is a symbol, it will be translated using the appropriate
           
        
      
        
          - 
            
            
            
            
    # scope (see +generate_message+).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If +type+ is a proc, it will be called, allowing for things like
           
        
      
        
          - 
            
            
            
            
    # <tt>Time.now</tt> to be used within an error.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If the <tt>:strict</tt> option is set to +true+, it will raise
           
        
      
        
          - 
            
            
            
            
    # ActiveModel::StrictValidationFailed instead of adding the error.
           
        
      
        
          - 
            
            
            
            
    # <tt>:strict</tt> option can also be set to any other exception.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :invalid, strict: true)
           
        
      
        
          - 
            
            
            
            
    #   # => ActiveModel::StrictValidationFailed: Name is invalid
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:name, :invalid, strict: NameIsInvalid)
           
        
      
        
          - 
            
            
            
            
    #   # => NameIsInvalid: Name is invalid
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages # => {}
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # +attribute+ should be set to <tt>:base</tt> if the error is not
           
        
      
        
          - 
            
            
            
            
    # directly associated with a single attribute.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add(:base, :name_or_email_blank,
           
        
      
        
          - 
            
            
            
            
    #     message: "either name or email must be present")
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages
           
        
      
        
          - 
            
            
            
            
    #   # => {:base=>["either name or email must be present"]}
           
        
      
        
          - 
            
            
            
            
    #   person.errors.details
           
        
      
        
          - 
            
            
            
            
    #   # => {:base=>[{error: :name_or_email_blank}]}
           
        
      
        
          - 
            1
            
            
            
    def add(attribute, type = :invalid, **options)
           
        
      
        
          - 
            669
            
            
            
      attribute, type, options = normalize_arguments(attribute, type, **options)
           
        
      
        
          - 
            669
            
            
            
      error = Error.new(@base, attribute, type, **options)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            669
            
            
            
      if exception = options[:strict]
           
        
      
        
          - 
            6
            
            
            
        exception = ActiveModel::StrictValidationFailed if exception == true
           
        
      
        
          - 
            6
            
            
            
        raise exception, error.full_message
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            663
            
            
            
      @errors.append(error)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            663
            
            
            
      error
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns +true+ if an error matches provided +attribute+ and +type+,
           
        
      
        
          - 
            
            
            
            
    # or +false+ otherwise. +type+ is treated the same as for +add+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add :name, :blank
           
        
      
        
          - 
            
            
            
            
    #   person.errors.added? :name, :blank           # => true
           
        
      
        
          - 
            
            
            
            
    #   person.errors.added? :name, "can't be blank" # => true
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If the error requires options, then it returns +true+ with
           
        
      
        
          - 
            
            
            
            
    # the correct options, or +false+ with incorrect or missing options.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   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
           
        
      
        
          - 
            1
            
            
            
    def added?(attribute, type = :invalid, options = {})
           
        
      
        
          - 
            28
            
            
            
      attribute, type, options = normalize_arguments(attribute, type, **options)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            28
            
            
            
      if type.is_a? Symbol
           
        
      
        
          - 
            19
            
            
            
        @errors.any? { |error|
           
        
      
        
          - 
            18
            
            
            
          error.strict_match?(attribute, type, **options)
           
        
      
        
          - 
            
            
            
            
        }
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            9
            
            
            
        messages_for(attribute).include?(type)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns +true+ if an error on the attribute with the given type is
           
        
      
        
          - 
            
            
            
            
    # present, or +false+ otherwise. +type+ is treated the same as for +add+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add :age
           
        
      
        
          - 
            
            
            
            
    #   person.errors.add :name, :too_long, { count: 25 }
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :age                                            # => true
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :name                                           # => false
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :name, :too_long                                # => true
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :name, "is too long (maximum is 25 characters)" # => true
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :name, :not_too_long                            # => false
           
        
      
        
          - 
            
            
            
            
    #   person.errors.of_kind? :name, "is too long"                            # => false
           
        
      
        
          - 
            1
            
            
            
    def of_kind?(attribute, type = :invalid)
           
        
      
        
          - 
            16
            
            
            
      attribute, type = normalize_arguments(attribute, type)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            16
            
            
            
      if type.is_a? Symbol
           
        
      
        
          - 
            8
            
            
            
        !where(attribute, type).empty?
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            8
            
            
            
        messages_for(attribute).include?(type)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all the full error messages in an array.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name, :address, :email
           
        
      
        
          - 
            
            
            
            
    #     validates_length_of :name, in: 5..30
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.create(address: '123 First St.')
           
        
      
        
          - 
            
            
            
            
    #   person.errors.full_messages
           
        
      
        
          - 
            
            
            
            
    #   # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
           
        
      
        
          - 
            1
            
            
            
    def full_messages
           
        
      
        
          - 
            22
            
            
            
      @errors.map(&:full_message)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    alias :to_a :full_messages
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all the full error messages for a given attribute in an array.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name, :email
           
        
      
        
          - 
            
            
            
            
    #     validates_length_of :name, in: 5..30
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.create()
           
        
      
        
          - 
            
            
            
            
    #   person.errors.full_messages_for(:name)
           
        
      
        
          - 
            
            
            
            
    #   # => ["Name is too short (minimum is 5 characters)", "Name can't be blank"]
           
        
      
        
          - 
            1
            
            
            
    def full_messages_for(attribute)
           
        
      
        
          - 
            4
            
            
            
      where(attribute).map(&:full_message).freeze
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns all the error messages for a given attribute in an array.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name, :email
           
        
      
        
          - 
            
            
            
            
    #     validates_length_of :name, in: 5..30
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.create()
           
        
      
        
          - 
            
            
            
            
    #   person.errors.messages_for(:name)
           
        
      
        
          - 
            
            
            
            
    #   # => ["is too short (minimum is 5 characters)", "can't be blank"]
           
        
      
        
          - 
            1
            
            
            
    def messages_for(attribute)
           
        
      
        
          - 
            768
            
            
            
      where(attribute).map(&:message)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a full message for a given attribute.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
           
        
      
        
          - 
            1
            
            
            
    def full_message(attribute, message)
           
        
      
        
          - 
            23
            
            
            
      Error.full_message(attribute, message, @base.class)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Translates an error message in its default scope
           
        
      
        
          - 
            
            
            
            
    # (<tt>activemodel.errors.messages</tt>).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Error messages are first looked up in <tt>activemodel.errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>,
           
        
      
        
          - 
            
            
            
            
    # if it's not there, it's looked up in <tt>activemodel.errors.models.MODEL.MESSAGE</tt> and if
           
        
      
        
          - 
            
            
            
            
    # that is not there also, it returns the translation of the default message
           
        
      
        
          - 
            
            
            
            
    # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model
           
        
      
        
          - 
            
            
            
            
    # name, translated attribute name and the value are available for
           
        
      
        
          - 
            
            
            
            
    # interpolation.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # When using inheritance in your models, it will check all the inherited
           
        
      
        
          - 
            
            
            
            
    # models too, but only if the model itself hasn't been found. Say you have
           
        
      
        
          - 
            
            
            
            
    # <tt>class Admin < User; end</tt> and you wanted the translation for
           
        
      
        
          - 
            
            
            
            
    # the <tt>:blank</tt> error message for the <tt>title</tt> attribute,
           
        
      
        
          - 
            
            
            
            
    # it looks for these translations:
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # * <tt>activemodel.errors.models.admin.attributes.title.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * <tt>activemodel.errors.models.admin.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * <tt>activemodel.errors.models.user.attributes.title.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * <tt>activemodel.errors.models.user.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * any default you provided through the +options+ hash (in the <tt>activemodel.errors</tt> scope)
           
        
      
        
          - 
            
            
            
            
    # * <tt>activemodel.errors.messages.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * <tt>errors.attributes.title.blank</tt>
           
        
      
        
          - 
            
            
            
            
    # * <tt>errors.messages.blank</tt>
           
        
      
        
          - 
            1
            
            
            
    def generate_message(attribute, type = :invalid, options = {})
           
        
      
        
          - 
            34
            
            
            
      Error.generate_message(attribute, type, @base, options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def marshal_load(array) # :nodoc:
           
        
      
        
          - 
            
            
            
            
      # Rails 5
           
        
      
        
          - 
            2
            
            
            
      @errors = []
           
        
      
        
          - 
            2
            
            
            
      @base = array[0]
           
        
      
        
          - 
            2
            
            
            
      add_from_legacy_details_hash(array[2])
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def init_with(coder) # :nodoc:
           
        
      
        
          - 
            6
            
            
            
      data = coder.map
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            6
            
            
            
      data.each { |k, v|
           
        
      
        
          - 
            14
            
            
            
        next if LEGACY_ATTRIBUTES.include?(k.to_sym)
           
        
      
        
          - 
            8
            
            
            
        instance_variable_set(:"@#{k}", v)
           
        
      
        
          - 
            
            
            
            
      }
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            6
            
            
            
      @errors ||= []
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Legacy support Rails 5.x details hash
           
        
      
        
          - 
            6
            
            
            
      add_from_legacy_details_hash(data["details"]) if data.key?("details")
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def normalize_arguments(attribute, type, **options)
           
        
      
        
          - 
            
            
            
            
        # Evaluate proc first
           
        
      
        
          - 
            1513
            
            
            
        if type.respond_to?(:call)
           
        
      
        
          - 
            7
            
            
            
          type = type.call(@base, options)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1513
            
            
            
        [attribute.to_sym, type, options]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def add_from_legacy_details_hash(details)
           
        
      
        
          - 
            4
            
            
            
        details.each { |attribute, errors|
           
        
      
        
          - 
            2
            
            
            
          errors.each { |error|
           
        
      
        
          - 
            2
            
            
            
            type = error.delete(:error)
           
        
      
        
          - 
            2
            
            
            
            add(attribute, type, **error)
           
        
      
        
          - 
            
            
            
            
          }
           
        
      
        
          - 
            
            
            
            
        }
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def deprecation_removal_warning(method_name, alternative_message = nil)
           
        
      
        
          - 
            12
            
            
            
        message = +"ActiveModel::Errors##{method_name} is deprecated and will be removed in Rails 6.2."
           
        
      
        
          - 
            12
            
            
            
        if alternative_message
           
        
      
        
          - 
            9
            
            
            
          message << "\n\nTo achieve the same use:\n\n  "
           
        
      
        
          - 
            9
            
            
            
          message << alternative_message
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            12
            
            
            
        ActiveSupport::Deprecation.warn(message)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def deprecation_rename_warning(old_method_name, new_method_name)
           
        
      
        
          - 
            
            
            
            
        ActiveSupport::Deprecation.warn("ActiveModel::Errors##{old_method_name} is deprecated. Please call ##{new_method_name} instead.")
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class DeprecationHandlingMessageHash < SimpleDelegator
           
        
      
        
          - 
            1
            
            
            
    def initialize(errors)
           
        
      
        
          - 
            102
            
            
            
      @errors = errors
           
        
      
        
          - 
            102
            
            
            
      super(prepare_content)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def []=(attribute, value)
           
        
      
        
          - 
            4
            
            
            
      ActiveSupport::Deprecation.warn("Calling `[]=` to an ActiveModel::Errors is deprecated. Please call `ActiveModel::Errors#add` instead.")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
      @errors.delete(attribute)
           
        
      
        
          - 
            4
            
            
            
      Array(value).each do |message|
           
        
      
        
          - 
            4
            
            
            
        @errors.add(attribute, message)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
      __setobj__ prepare_content
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def delete(attribute)
           
        
      
        
          - 
            1
            
            
            
      ActiveSupport::Deprecation.warn("Calling `delete` to an ActiveModel::Errors messages hash is deprecated. Please call `ActiveModel::Errors#delete` instead.")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      @errors.delete(attribute)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def prepare_content
           
        
      
        
          - 
            106
            
            
            
        content = @errors.to_hash
           
        
      
        
          - 
            106
            
            
            
        content.each do |attribute, value|
           
        
      
        
          - 
            100
            
            
            
          content[attribute] = DeprecationHandlingMessageArray.new(value, @errors, attribute)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            106
            
            
            
        content.default_proc = proc do |hash, attribute|
           
        
      
        
          - 
            8
            
            
            
          hash = hash.dup
           
        
      
        
          - 
            8
            
            
            
          hash[attribute] = DeprecationHandlingMessageArray.new([], @errors, attribute)
           
        
      
        
          - 
            8
            
            
            
          __setobj__ hash.freeze
           
        
      
        
          - 
            8
            
            
            
          hash[attribute]
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            106
            
            
            
        content.freeze
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class DeprecationHandlingMessageArray < SimpleDelegator
           
        
      
        
          - 
            1
            
            
            
    def initialize(content, errors, attribute)
           
        
      
        
          - 
            855
            
            
            
      @errors = errors
           
        
      
        
          - 
            855
            
            
            
      @attribute = attribute
           
        
      
        
          - 
            855
            
            
            
      super(content.freeze)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def <<(message)
           
        
      
        
          - 
            4
            
            
            
      ActiveSupport::Deprecation.warn("Calling `<<` to an ActiveModel::Errors message array in order to add an error is deprecated. Please call `ActiveModel::Errors#add` instead.")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
      @errors.add(@attribute, message)
           
        
      
        
          - 
            4
            
            
            
      __setobj__ @errors.messages_for(@attribute)
           
        
      
        
          - 
            4
            
            
            
      self
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def clear
           
        
      
        
          - 
            1
            
            
            
      ActiveSupport::Deprecation.warn("Calling `clear` to an ActiveModel::Errors message array in order to delete all errors is deprecated. Please call `ActiveModel::Errors#delete` instead.")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      @errors.delete(@attribute)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  class DeprecationHandlingDetailsHash < SimpleDelegator
           
        
      
        
          - 
            1
            
            
            
    def initialize(details)
           
        
      
        
          - 
            20
            
            
            
      details.default = []
           
        
      
        
          - 
            20
            
            
            
      details.freeze
           
        
      
        
          - 
            20
            
            
            
      super(details)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # Raised when a validation cannot be corrected by end users and are considered
           
        
      
        
          - 
            
            
            
            
  # exceptional.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     validates_presence_of :name, strict: true
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.name = nil
           
        
      
        
          - 
            
            
            
            
  #   person.valid?
           
        
      
        
          - 
            
            
            
            
  #   # => ActiveModel::StrictValidationFailed: Name can't be blank
           
        
      
        
          - 
            1
            
            
            
  class StrictValidationFailed < StandardError
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # Raised when attribute values are out of range.
           
        
      
        
          - 
            1
            
            
            
  class RangeError < ::RangeError
           
        
      
        
          - 
            
            
            
            
  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.
           
        
      
        
          - 
            1
            
            
            
  class UnknownAttributeError < NoMethodError
           
        
      
        
          - 
            1
            
            
            
    attr_reader :record, :attribute
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(record, attribute)
           
        
      
        
          - 
            4
            
            
            
      @record = record
           
        
      
        
          - 
            4
            
            
            
      @attribute = attribute
           
        
      
        
          - 
            4
            
            
            
      super("unknown attribute '#{attribute}' for #{@record.class}.")
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # Raised when forbidden attributes are used for mass assignment.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   params = ActionController::Parameters.new(name: 'Bob')
           
        
      
        
          - 
            
            
            
            
  #   Person.new(params)
           
        
      
        
          - 
            
            
            
            
  #   # => ActiveModel::ForbiddenAttributesError
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   params.permit!
           
        
      
        
          - 
            
            
            
            
  #   Person.new(params)
           
        
      
        
          - 
            
            
            
            
  #   # => #<Person id: nil, name: "Bob">
           
        
      
        
          - 
            1
            
            
            
  class ForbiddenAttributesError < StandardError
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  module ForbiddenAttributesProtection # :nodoc:
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def sanitize_for_mass_assignment(attributes)
           
        
      
        
          - 
            22
            
            
            
        if attributes.respond_to?(:permitted?)
           
        
      
        
          - 
            4
            
            
            
          raise ActiveModel::ForbiddenAttributesError if !attributes.permitted?
           
        
      
        
          - 
            2
            
            
            
          attributes.to_h
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            18
            
            
            
          attributes
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            1
            
            
            
      alias :sanitize_forbidden_attributes :sanitize_for_mass_assignment
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt>
           
        
      
        
          - 
            1
            
            
            
  def self.gem_version
           
        
      
        
          - 
            
            
            
            
    Gem::Version.new VERSION::STRING
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  module VERSION
           
        
      
        
          - 
            1
            
            
            
    MAJOR = 6
           
        
      
        
          - 
            1
            
            
            
    MINOR = 1
           
        
      
        
          - 
            1
            
            
            
    TINY  = 0
           
        
      
        
          - 
            1
            
            
            
    PRE   = "alpha"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Lint
           
        
      
        
          - 
            
            
            
            
    # == Active \Model \Lint \Tests
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # You can test whether an object is compliant with the Active \Model API by
           
        
      
        
          - 
            
            
            
            
    # including <tt>ActiveModel::Lint::Tests</tt> in your TestCase. It will
           
        
      
        
          - 
            
            
            
            
    # include tests that tell you whether your object is fully compliant,
           
        
      
        
          - 
            
            
            
            
    # or if not, which aspects of the API are not implemented.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Note an object is not required to implement all APIs in order to work
           
        
      
        
          - 
            
            
            
            
    # with Action Pack. This module only intends to provide guidance in case
           
        
      
        
          - 
            
            
            
            
    # you want all features out of the box.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # These tests do not attempt to determine the semantic correctness of the
           
        
      
        
          - 
            
            
            
            
    # returned values. For instance, you could implement <tt>valid?</tt> to
           
        
      
        
          - 
            
            
            
            
    # always return +true+, and the tests would pass. It is up to you to ensure
           
        
      
        
          - 
            
            
            
            
    # that the values are semantically meaningful.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Objects you pass in are expected to return a compliant object from a call
           
        
      
        
          - 
            
            
            
            
    # to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return
           
        
      
        
          - 
            
            
            
            
    # +self+.
           
        
      
        
          - 
            1
            
            
            
    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.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # <tt>to_key</tt> returns an Enumerable of all (primary) key attributes
           
        
      
        
          - 
            
            
            
            
      # of the model, and is used to a generate unique DOM id for the object.
           
        
      
        
          - 
            1
            
            
            
      def test_to_key
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :to_key
           
        
      
        
          - 
            2
            
            
            
        def model.persisted?() false end
           
        
      
        
          - 
            2
            
            
            
        assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false"
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Passes if the object's model responds to <tt>to_param</tt> and if
           
        
      
        
          - 
            
            
            
            
      # calling this method returns +nil+ when the object is not persisted.
           
        
      
        
          - 
            
            
            
            
      # Fails otherwise.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # <tt>to_param</tt> is used to represent the object's key in URLs.
           
        
      
        
          - 
            
            
            
            
      # Implementers can decide to either raise an exception or provide a
           
        
      
        
          - 
            
            
            
            
      # default in case the record uses a composite primary key. There are no
           
        
      
        
          - 
            
            
            
            
      # tests for this behavior in lint because it doesn't make sense to force
           
        
      
        
          - 
            
            
            
            
      # any of the possible implementation strategies on the implementer.
           
        
      
        
          - 
            1
            
            
            
      def test_to_param
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :to_param
           
        
      
        
          - 
            2
            
            
            
        def model.to_key() [1] end
           
        
      
        
          - 
            4
            
            
            
        def model.persisted?() false end
           
        
      
        
          - 
            2
            
            
            
        assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false"
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Passes if the object's model responds to <tt>to_partial_path</tt> and if
           
        
      
        
          - 
            
            
            
            
      # calling this method returns a string. Fails otherwise.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # <tt>to_partial_path</tt> is used for looking up partials. For example,
           
        
      
        
          - 
            
            
            
            
      # a BlogPost model might return "blog_posts/blog_post".
           
        
      
        
          - 
            1
            
            
            
      def test_to_partial_path
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :to_partial_path
           
        
      
        
          - 
            2
            
            
            
        assert_kind_of String, model.to_partial_path
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Passes if the object's model responds to <tt>persisted?</tt> and if
           
        
      
        
          - 
            
            
            
            
      # calling this method returns either +true+ or +false+. Fails otherwise.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # <tt>persisted?</tt> is used when calculating the URL for an object.
           
        
      
        
          - 
            
            
            
            
      # If the object is not persisted, a form for that object, for instance,
           
        
      
        
          - 
            
            
            
            
      # will route to the create action. If it is persisted, a form for the
           
        
      
        
          - 
            
            
            
            
      # object will route to the update action.
           
        
      
        
          - 
            1
            
            
            
      def test_persisted?
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :persisted?
           
        
      
        
          - 
            2
            
            
            
        assert_boolean model.persisted?, "persisted?"
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Passes if the object's model responds to <tt>model_name</tt> both as
           
        
      
        
          - 
            
            
            
            
      # an instance method and as a class method, and if calling this method
           
        
      
        
          - 
            
            
            
            
      # returns a string with some convenience methods: <tt>:human</tt>,
           
        
      
        
          - 
            
            
            
            
      # <tt>:singular</tt> and <tt>:plural</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Check ActiveModel::Naming for more information.
           
        
      
        
          - 
            1
            
            
            
      def test_model_naming
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model.class, :model_name
           
        
      
        
          - 
            2
            
            
            
        model_name = model.class.model_name
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model_name, :to_str
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model_name.human, :to_str
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model_name.singular, :to_str
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model_name.plural, :to_str
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :model_name
           
        
      
        
          - 
            2
            
            
            
        assert_equal model.model_name, model.class.model_name
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Passes if the object's model responds to <tt>errors</tt> and if calling
           
        
      
        
          - 
            
            
            
            
      # <tt>[](attribute)</tt> on the result of this method returns an array.
           
        
      
        
          - 
            
            
            
            
      # Fails otherwise.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # <tt>errors[attribute]</tt> is used to retrieve the errors of a model
           
        
      
        
          - 
            
            
            
            
      # for a given attribute. If errors are present, the method should return
           
        
      
        
          - 
            
            
            
            
      # an array of strings that are the errors for the attribute in question.
           
        
      
        
          - 
            
            
            
            
      # If localization is used, the strings should be localized for the current
           
        
      
        
          - 
            
            
            
            
      # locale. If no error is present, the method should return an empty array.
           
        
      
        
          - 
            1
            
            
            
      def test_errors_aref
           
        
      
        
          - 
            2
            
            
            
        assert_respond_to model, :errors
           
        
      
        
          - 
            2
            
            
            
        assert_equal [], model.errors[:hello], "errors#[] should return an empty Array"
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def model
           
        
      
        
          - 
            36
            
            
            
          assert_respond_to @model, :to_model
           
        
      
        
          - 
            36
            
            
            
          @model.to_model
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def assert_boolean(result, name)
           
        
      
        
          - 
            2
            
            
            
          assert result == true || result == false, "#{name} should be a boolean"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Basic \Model
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Includes the required interface for an object to interact with
           
        
      
        
          - 
            
            
            
            
  # Action Pack and Action View, using different Active Model modules.
           
        
      
        
          - 
            
            
            
            
  # It includes model name introspections, conversions, translations and
           
        
      
        
          - 
            
            
            
            
  # validations. Besides that, it allows you to initialize the object with a
           
        
      
        
          - 
            
            
            
            
  # hash of attributes, pretty much like Active Record does.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Model
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name, :age
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new(name: 'bob', age: '18')
           
        
      
        
          - 
            
            
            
            
  #   person.name # => "bob"
           
        
      
        
          - 
            
            
            
            
  #   person.age  # => "18"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt>
           
        
      
        
          - 
            
            
            
            
  # to return +false+, which is the most common case. You may want to override
           
        
      
        
          - 
            
            
            
            
  # it in your class to simulate a different scenario:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Model
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :id, :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def persisted?
           
        
      
        
          - 
            
            
            
            
  #       self.id == 1
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new(id: 1, name: 'bob')
           
        
      
        
          - 
            
            
            
            
  #   person.persisted? # => true
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Also, if for some reason you need to run code on <tt>initialize</tt>, make
           
        
      
        
          - 
            
            
            
            
  # sure you call +super+ if you want the attributes hash initialization to
           
        
      
        
          - 
            
            
            
            
  # happen.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Model
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :id, :name, :omg
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def initialize(attributes={})
           
        
      
        
          - 
            
            
            
            
  #       super
           
        
      
        
          - 
            
            
            
            
  #       @omg ||= true
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new(id: 1, name: 'bob')
           
        
      
        
          - 
            
            
            
            
  #   person.omg # => true
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # For more detailed information on other functionalities available, please
           
        
      
        
          - 
            
            
            
            
  # refer to the specific modules included in <tt>ActiveModel::Model</tt>
           
        
      
        
          - 
            
            
            
            
  # (see below).
           
        
      
        
          - 
            1
            
            
            
  module Model
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::AttributeAssignment
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::Validations
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::Conversion
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    included do
           
        
      
        
          - 
            5
            
            
            
      extend ActiveModel::Naming
           
        
      
        
          - 
            5
            
            
            
      extend ActiveModel::Translation
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Initializes a new model with the given +params+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Model
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name, :age
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new(name: 'bob', age: '18')
           
        
      
        
          - 
            
            
            
            
    #   person.name # => "bob"
           
        
      
        
          - 
            
            
            
            
    #   person.age  # => "18"
           
        
      
        
          - 
            1
            
            
            
    def initialize(attributes = {})
           
        
      
        
          - 
            52
            
            
            
      assign_attributes(attributes) if attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            50
            
            
            
      super()
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Indicates if the model is persisted. Default is +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #  class Person
           
        
      
        
          - 
            
            
            
            
    #    include ActiveModel::Model
           
        
      
        
          - 
            
            
            
            
    #    attr_accessor :id, :name
           
        
      
        
          - 
            
            
            
            
    #  end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #  person = Person.new(id: 1, name: 'bob')
           
        
      
        
          - 
            
            
            
            
    #  person.persisted? # => false
           
        
      
        
          - 
            1
            
            
            
    def persisted?
           
        
      
        
          - 
            2
            
            
            
      false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/hash/except"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/module/introspection"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/module/redefine_method"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class Name
           
        
      
        
          - 
            1
            
            
            
    include Comparable
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    attr_reader :singular, :plural, :element, :collection,
           
        
      
        
          - 
            
            
            
            
      :singular_route_key, :route_key, :param_key, :i18n_key,
           
        
      
        
          - 
            
            
            
            
      :name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    alias_method :cache_key, :collection
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: ==
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   ==(other)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#==</tt>. Returns +true+ if the class name and
           
        
      
        
          - 
            
            
            
            
    # +other+ are equal, otherwise +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name == 'BlogPost'  # => true
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name == 'Blog Post' # => false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: ===
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   ===(other)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>#==</tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name === 'BlogPost'  # => true
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name === 'Blog Post' # => false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: <=>
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   <=>(other)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#<=></tt>.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name <=> 'BlogPost'  # => 0
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name <=> 'Blog'      # => 1
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name <=> 'BlogPosts' # => -1
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: =~
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   =~(regexp)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#=~</tt>. Match the class name against the given
           
        
      
        
          - 
            
            
            
            
    # regexp. Returns the position where the match starts or +nil+ if there is
           
        
      
        
          - 
            
            
            
            
    # no match.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name =~ /Post/ # => 4
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name =~ /\d/   # => nil
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: !~
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   !~(regexp)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#!~</tt>. Match the class name against the given
           
        
      
        
          - 
            
            
            
            
    # regexp. Returns +true+ if there is no match, otherwise +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name !~ /Post/ # => false
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name !~ /\d/   # => true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: eql?
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   eql?(other)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#eql?</tt>. Returns +true+ if the class name and
           
        
      
        
          - 
            
            
            
            
    # +other+ have the same length and content, otherwise +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.eql?('BlogPost')  # => true
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.eql?('Blog Post') # => false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: match?
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   match?(regexp)
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to <tt>String#match?</tt>. Match the class name against the
           
        
      
        
          - 
            
            
            
            
    # given regexp. Returns +true+ if there is a match, otherwise +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.match?(/Post/) # => true
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.match?(/\d/) # => false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: to_s
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   to_s()
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Returns the class name.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.to_s # => "BlogPost"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    ##
           
        
      
        
          - 
            
            
            
            
    # :method: to_str
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # :call-seq:
           
        
      
        
          - 
            
            
            
            
    #   to_str()
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Equivalent to +to_s+.
           
        
      
        
          - 
            1
            
            
            
    delegate :==, :===, :<=>, :=~, :"!~", :eql?, :match?, :to_s,
           
        
      
        
          - 
            
            
            
            
             :to_str, :as_json, to: :name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a new ActiveModel::Name instance. By default, the +namespace+
           
        
      
        
          - 
            
            
            
            
    # and +name+ option will take the namespace and name of the given class
           
        
      
        
          - 
            
            
            
            
    # respectively.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   module Foo
           
        
      
        
          - 
            
            
            
            
    #     class Bar
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Name.new(Foo::Bar).to_s
           
        
      
        
          - 
            
            
            
            
    #   # => "Foo::Bar"
           
        
      
        
          - 
            1
            
            
            
    def initialize(klass, namespace = nil, name = nil)
           
        
      
        
          - 
            118
            
            
            
      @name = name || klass.name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            118
            
            
            
      raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            117
            
            
            
      @unnamespaced = @name.delete_prefix("#{namespace.name}::") if namespace
           
        
      
        
          - 
            117
            
            
            
      @klass        = klass
           
        
      
        
          - 
            117
            
            
            
      @singular     = _singularize(@name)
           
        
      
        
          - 
            117
            
            
            
      @plural       = ActiveSupport::Inflector.pluralize(@singular)
           
        
      
        
          - 
            117
            
            
            
      @element      = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name))
           
        
      
        
          - 
            117
            
            
            
      @human        = ActiveSupport::Inflector.humanize(@element)
           
        
      
        
          - 
            117
            
            
            
      @collection   = ActiveSupport::Inflector.tableize(@name)
           
        
      
        
          - 
            117
            
            
            
      @param_key    = (namespace ? _singularize(@unnamespaced) : @singular)
           
        
      
        
          - 
            117
            
            
            
      @i18n_key     = @name.underscore.to_sym
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            117
            
            
            
      @route_key          = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup)
           
        
      
        
          - 
            117
            
            
            
      @singular_route_key = ActiveSupport::Inflector.singularize(@route_key)
           
        
      
        
          - 
            117
            
            
            
      @route_key << "_index" if @plural == @singular
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Transform the model name into a more human format, using I18n. By default,
           
        
      
        
          - 
            
            
            
            
    # it will underscore then humanize the class name.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class BlogPost
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   BlogPost.model_name.human # => "Blog post"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Specify +options+ with additional translating options.
           
        
      
        
          - 
            1
            
            
            
    def human(options = {})
           
        
      
        
          - 
            571
            
            
            
      return @human unless @klass.respond_to?(:lookup_ancestors) &&
           
        
      
        
          - 
            
            
            
            
                           @klass.respond_to?(:i18n_scope)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            519
            
            
            
      defaults = @klass.lookup_ancestors.map do |klass|
           
        
      
        
          - 
            572
            
            
            
        klass.model_name.i18n_key
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            519
            
            
            
      defaults << options[:default] if options[:default]
           
        
      
        
          - 
            519
            
            
            
      defaults << @human
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            519
            
            
            
      options = { scope: [@klass.i18n_scope, :models], count: 1, default: defaults }.merge!(options.except(:default))
           
        
      
        
          - 
            519
            
            
            
      I18n.translate(defaults.shift, **options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def _singularize(string)
           
        
      
        
          - 
            126
            
            
            
        ActiveSupport::Inflector.underscore(string).tr("/", "_")
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Naming
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Creates a +model_name+ method on your object.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # To implement, just extend ActiveModel::Naming in your object:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class BookCover
           
        
      
        
          - 
            
            
            
            
  #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   BookCover.model_name.name   # => "BookCover"
           
        
      
        
          - 
            
            
            
            
  #   BookCover.model_name.human  # => "Book cover"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   BookCover.model_name.i18n_key              # => :book_cover
           
        
      
        
          - 
            
            
            
            
  #   BookModule::BookCover.model_name.i18n_key  # => :"book_module/book_cover"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Providing the functionality that ActiveModel::Naming provides in your object
           
        
      
        
          - 
            
            
            
            
  # is required to pass the \Active \Model Lint test. So either extending the
           
        
      
        
          - 
            
            
            
            
  # provided method below, or rolling your own is required.
           
        
      
        
          - 
            1
            
            
            
  module Naming
           
        
      
        
          - 
            1
            
            
            
    def self.extended(base) #:nodoc:
           
        
      
        
          - 
            27
            
            
            
      base.silence_redefinition_of_method :model_name
           
        
      
        
          - 
            27
            
            
            
      base.delegate :model_name, to: :class
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns an ActiveModel::Name object for module. It can be
           
        
      
        
          - 
            
            
            
            
    # used to retrieve all kinds of naming-related information
           
        
      
        
          - 
            
            
            
            
    # (See ActiveModel::Name for more information).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   Person.model_name.name     # => "Person"
           
        
      
        
          - 
            
            
            
            
    #   Person.model_name.class    # => ActiveModel::Name
           
        
      
        
          - 
            
            
            
            
    #   Person.model_name.singular # => "person"
           
        
      
        
          - 
            
            
            
            
    #   Person.model_name.plural   # => "people"
           
        
      
        
          - 
            1
            
            
            
    def model_name
           
        
      
        
          - 
            3048
            
            
            
      @_model_name ||= begin
           
        
      
        
          - 
            84
            
            
            
        namespace = module_parents.detect do |n|
           
        
      
        
          - 
            158
            
            
            
          n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            84
            
            
            
        ActiveModel::Name.new(self, namespace)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the plural class name of a record or class.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.plural(post)             # => "posts"
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people"
           
        
      
        
          - 
            1
            
            
            
    def self.plural(record_or_class)
           
        
      
        
          - 
            5
            
            
            
      model_name_from_record_or_class(record_or_class).plural
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the singular class name of a record or class.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.singular(post)             # => "post"
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person"
           
        
      
        
          - 
            1
            
            
            
    def self.singular(record_or_class)
           
        
      
        
          - 
            4
            
            
            
      model_name_from_record_or_class(record_or_class).singular
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Identifies whether the class name of a record or class is uncountable.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.uncountable?(Sheep) # => true
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.uncountable?(Post)  # => false
           
        
      
        
          - 
            1
            
            
            
    def self.uncountable?(record_or_class)
           
        
      
        
          - 
            2
            
            
            
      plural(record_or_class) == singular(record_or_class)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns string to use while generating route names. It differs for
           
        
      
        
          - 
            
            
            
            
    # namespaced models regarding whether it's inside isolated engine.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For isolated engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.singular_route_key(Blog::Post) # => "post"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For shared engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.singular_route_key(Blog::Post) # => "blog_post"
           
        
      
        
          - 
            1
            
            
            
    def self.singular_route_key(record_or_class)
           
        
      
        
          - 
            3
            
            
            
      model_name_from_record_or_class(record_or_class).singular_route_key
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns string to use while generating route names. It differs for
           
        
      
        
          - 
            
            
            
            
    # namespaced models regarding whether it's inside isolated engine.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For isolated engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.route_key(Blog::Post) # => "posts"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For shared engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.route_key(Blog::Post) # => "blog_posts"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # The route key also considers if the noun is uncountable and, in
           
        
      
        
          - 
            
            
            
            
    # such cases, automatically appends _index.
           
        
      
        
          - 
            1
            
            
            
    def self.route_key(record_or_class)
           
        
      
        
          - 
            3
            
            
            
      model_name_from_record_or_class(record_or_class).route_key
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns string to use for params names. It differs for
           
        
      
        
          - 
            
            
            
            
    # namespaced models regarding whether it's inside isolated engine.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For isolated engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.param_key(Blog::Post) # => "post"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   # For shared engine:
           
        
      
        
          - 
            
            
            
            
    #   ActiveModel::Naming.param_key(Blog::Post) # => "blog_post"
           
        
      
        
          - 
            1
            
            
            
    def self.param_key(record_or_class)
           
        
      
        
          - 
            2
            
            
            
      model_name_from_record_or_class(record_or_class).param_key
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def self.model_name_from_record_or_class(record_or_class) #:nodoc:
           
        
      
        
          - 
            17
            
            
            
      if record_or_class.respond_to?(:to_model)
           
        
      
        
          - 
            6
            
            
            
        record_or_class.to_model.model_name
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            11
            
            
            
        record_or_class.model_name
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    private_class_method :model_name_from_record_or_class
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/error"
           
        
      
        
          - 
            1
            
            
            
require "forwardable"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  class NestedError < Error
           
        
      
        
          - 
            1
            
            
            
    def initialize(base, inner_error, override_options = {})
           
        
      
        
          - 
            7
            
            
            
      @base = base
           
        
      
        
          - 
            7
            
            
            
      @inner_error = inner_error
           
        
      
        
          - 
            12
            
            
            
      @attribute = override_options.fetch(:attribute) { inner_error.attribute }
           
        
      
        
          - 
            13
            
            
            
      @type = override_options.fetch(:type) { inner_error.type }
           
        
      
        
          - 
            7
            
            
            
      @raw_type = inner_error.raw_type
           
        
      
        
          - 
            7
            
            
            
      @options = inner_error.options
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    attr_reader :inner_error
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    extend Forwardable
           
        
      
        
          - 
            1
            
            
            
    def_delegators :@inner_error, :message
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
require "active_model"
           
        
      
        
          - 
            
            
            
            
require "rails"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  class Railtie < Rails::Railtie # :nodoc:
           
        
      
        
          - 
            
            
            
            
    config.eager_load_namespaces << ActiveModel
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    config.active_model = ActiveSupport::OrderedOptions.new
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    initializer "active_model.secure_password" do
           
        
      
        
          - 
            
            
            
            
      ActiveModel::SecurePassword.min_cost = Rails.env.test?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    initializer "active_model.i18n_customize_full_message" do
           
        
      
        
          - 
            
            
            
            
      ActiveModel::Error.i18n_customize_full_message = config.active_model.delete(:i18n_customize_full_message) || false
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module SecurePassword
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # BCrypt hash function can handle maximum 72 bytes, and if we pass
           
        
      
        
          - 
            
            
            
            
    # password of length more than 72 bytes it ignores extra characters.
           
        
      
        
          - 
            
            
            
            
    # Hence need to put a restriction on password length.
           
        
      
        
          - 
            1
            
            
            
    MAX_PASSWORD_LENGTH_ALLOWED = 72
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    class << self
           
        
      
        
          - 
            1
            
            
            
      attr_accessor :min_cost # :nodoc:
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            1
            
            
            
    self.min_cost = false
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            
            
            
            
      # Adds methods to set and authenticate against a BCrypt password.
           
        
      
        
          - 
            
            
            
            
      # This mechanism requires you to have a +XXX_digest+ attribute.
           
        
      
        
          - 
            
            
            
            
      # Where +XXX+ is the attribute name of your desired password.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The following validations are added automatically:
           
        
      
        
          - 
            
            
            
            
      # * Password must be present on creation
           
        
      
        
          - 
            
            
            
            
      # * Password length should be less than or equal to 72 bytes
           
        
      
        
          - 
            
            
            
            
      # * Confirmation of password (using a +XXX_confirmation+ attribute)
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If confirmation validation is not needed, simply leave out the
           
        
      
        
          - 
            
            
            
            
      # value for +XXX_confirmation+ (i.e. don't provide a form field for
           
        
      
        
          - 
            
            
            
            
      # it). When this attribute has a +nil+ value, the validation will not be
           
        
      
        
          - 
            
            
            
            
      # triggered.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # For further customizability, it is possible to suppress the default
           
        
      
        
          - 
            
            
            
            
      # validations by passing <tt>validations: false</tt> as an argument.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   gem 'bcrypt', '~> 3.1.7'
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Example using Active Record (which automatically includes ActiveModel::SecurePassword):
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   # Schema: User(name:string, password_digest:string, recovery_password_digest:string)
           
        
      
        
          - 
            
            
            
            
      #   class User < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     has_secure_password
           
        
      
        
          - 
            
            
            
            
      #     has_secure_password :recovery_password, validations: false
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
           
        
      
        
          - 
            
            
            
            
      #   user.save                                                  # => false, password required
           
        
      
        
          - 
            
            
            
            
      #   user.password = 'mUc3m00RsqyRe'
           
        
      
        
          - 
            
            
            
            
      #   user.save                                                  # => false, confirmation doesn't match
           
        
      
        
          - 
            
            
            
            
      #   user.password_confirmation = 'mUc3m00RsqyRe'
           
        
      
        
          - 
            
            
            
            
      #   user.save                                                  # => true
           
        
      
        
          - 
            
            
            
            
      #   user.recovery_password = "42password"
           
        
      
        
          - 
            
            
            
            
      #   user.recovery_password_digest                              # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
           
        
      
        
          - 
            
            
            
            
      #   user.save                                                  # => true
           
        
      
        
          - 
            
            
            
            
      #   user.authenticate('notright')                              # => false
           
        
      
        
          - 
            
            
            
            
      #   user.authenticate('mUc3m00RsqyRe')                         # => user
           
        
      
        
          - 
            
            
            
            
      #   user.authenticate_recovery_password('42password')          # => user
           
        
      
        
          - 
            
            
            
            
      #   User.find_by(name: 'david')&.authenticate('notright')      # => false
           
        
      
        
          - 
            
            
            
            
      #   User.find_by(name: 'david')&.authenticate('mUc3m00RsqyRe') # => user
           
        
      
        
          - 
            1
            
            
            
      def has_secure_password(attribute = :password, validations: true)
           
        
      
        
          - 
            
            
            
            
        # Load bcrypt gem only when has_secure_password is used.
           
        
      
        
          - 
            
            
            
            
        # This is to avoid ActiveModel (and by extension the entire framework)
           
        
      
        
          - 
            
            
            
            
        # being dependent on a binary library.
           
        
      
        
          - 
            3
            
            
            
        begin
           
        
      
        
          - 
            3
            
            
            
          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
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        include InstanceMethodsOnActivation.new(attribute)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        if validations
           
        
      
        
          - 
            1
            
            
            
          include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          # This ensures the model has a password by checking whether the password_digest
           
        
      
        
          - 
            
            
            
            
          # is present, so that this works with both new and existing records. However,
           
        
      
        
          - 
            
            
            
            
          # when there is an error, the message is added to the password attribute instead
           
        
      
        
          - 
            
            
            
            
          # so that the error message will make sense to the end-user.
           
        
      
        
          - 
            1
            
            
            
          validate do |record|
           
        
      
        
          - 
            22
            
            
            
            record.errors.add(attribute, :blank) unless record.send("#{attribute}_digest").present?
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          validates_length_of attribute, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
           
        
      
        
          - 
            1
            
            
            
          validates_confirmation_of attribute, allow_blank: true
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    class InstanceMethodsOnActivation < Module
           
        
      
        
          - 
            1
            
            
            
      def initialize(attribute)
           
        
      
        
          - 
            3
            
            
            
        attr_reader attribute
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        define_method("#{attribute}=") do |unencrypted_password|
           
        
      
        
          - 
            28
            
            
            
          if unencrypted_password.nil?
           
        
      
        
          - 
            3
            
            
            
            self.send("#{attribute}_digest=", nil)
           
        
      
        
          - 
            25
            
            
            
          elsif !unencrypted_password.empty?
           
        
      
        
          - 
            21
            
            
            
            instance_variable_set("@#{attribute}", unencrypted_password)
           
        
      
        
          - 
            21
            
            
            
            cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
           
        
      
        
          - 
            21
            
            
            
            self.send("#{attribute}_digest=", BCrypt::Password.create(unencrypted_password, cost: cost))
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        define_method("#{attribute}_confirmation=") do |unencrypted_password|
           
        
      
        
          - 
            13
            
            
            
          instance_variable_set("@#{attribute}_confirmation", unencrypted_password)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # Returns +self+ if the password is correct, otherwise +false+.
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   class User < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
        #     has_secure_password validations: false
           
        
      
        
          - 
            
            
            
            
        #   end
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
           
        
      
        
          - 
            
            
            
            
        #   user.save
           
        
      
        
          - 
            
            
            
            
        #   user.authenticate_password('notright')      # => false
           
        
      
        
          - 
            
            
            
            
        #   user.authenticate_password('mUc3m00RsqyRe') # => user
           
        
      
        
          - 
            3
            
            
            
        define_method("authenticate_#{attribute}") do |unencrypted_password|
           
        
      
        
          - 
            6
            
            
            
          attribute_digest = send("#{attribute}_digest")
           
        
      
        
          - 
            6
            
            
            
          BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        alias_method :authenticate, :authenticate_password if attribute == :password
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Serialization
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides a basic serialization to a serializable_hash for your objects.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Serialization
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def attributes
           
        
      
        
          - 
            
            
            
            
  #       {'name' => nil}
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Which would provide you with:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash   # => {"name"=>nil}
           
        
      
        
          - 
            
            
            
            
  #   person.name = "Bob"
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash   # => {"name"=>"Bob"}
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # An +attributes+ hash must be defined and should contain any attributes you
           
        
      
        
          - 
            
            
            
            
  # need to be serialized. Attributes must be strings, not symbols.
           
        
      
        
          - 
            
            
            
            
  # When called, serializable hash will use instance methods that match the name
           
        
      
        
          - 
            
            
            
            
  # of the attributes hash's keys. In order to override this behavior, take a look
           
        
      
        
          - 
            
            
            
            
  # at the private method +read_attribute_for_serialization+.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # ActiveModel::Serializers::JSON module automatically includes
           
        
      
        
          - 
            
            
            
            
  # the <tt>ActiveModel::Serialization</tt> module, so there is no need to
           
        
      
        
          - 
            
            
            
            
  # explicitly include <tt>ActiveModel::Serialization</tt>.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation including JSON would be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Serializers::JSON
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     def attributes
           
        
      
        
          - 
            
            
            
            
  #       {'name' => nil}
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Which would provide you with:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash   # => {"name"=>nil}
           
        
      
        
          - 
            
            
            
            
  #   person.as_json             # => {"name"=>nil}
           
        
      
        
          - 
            
            
            
            
  #   person.to_json             # => "{\"name\":null}"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.name = "Bob"
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash   # => {"name"=>"Bob"}
           
        
      
        
          - 
            
            
            
            
  #   person.as_json             # => {"name"=>"Bob"}
           
        
      
        
          - 
            
            
            
            
  #   person.to_json             # => "{\"name\":\"Bob\"}"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and
           
        
      
        
          - 
            
            
            
            
  # <tt>:include</tt>. The following are all valid examples:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash(only: 'name')
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash(include: :address)
           
        
      
        
          - 
            
            
            
            
  #   person.serializable_hash(include: { address: { only: 'city' }})
           
        
      
        
          - 
            1
            
            
            
  module Serialization
           
        
      
        
          - 
            
            
            
            
    # Returns a serialized hash of your object.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Serialization
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name, :age
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def attributes
           
        
      
        
          - 
            
            
            
            
    #       {'name' => nil, 'age' => nil}
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def capitalized_name
           
        
      
        
          - 
            
            
            
            
    #       name.capitalize
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'bob'
           
        
      
        
          - 
            
            
            
            
    #   person.age  = 22
           
        
      
        
          - 
            
            
            
            
    #   person.serializable_hash                # => {"name"=>"bob", "age"=>22}
           
        
      
        
          - 
            
            
            
            
    #   person.serializable_hash(only: :name)   # => {"name"=>"bob"}
           
        
      
        
          - 
            
            
            
            
    #   person.serializable_hash(except: :name) # => {"age"=>22}
           
        
      
        
          - 
            
            
            
            
    #   person.serializable_hash(methods: :capitalized_name)
           
        
      
        
          - 
            
            
            
            
    #   # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Example with <tt>:include</tt> option
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class User
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Serializers::JSON
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name, :notes # Emulate has_many :notes
           
        
      
        
          - 
            
            
            
            
    #     def attributes
           
        
      
        
          - 
            
            
            
            
    #       {'name' => nil}
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Note
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Serializers::JSON
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :title, :text
           
        
      
        
          - 
            
            
            
            
    #     def attributes
           
        
      
        
          - 
            
            
            
            
    #       {'title' => nil, 'text' => nil}
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   note = Note.new
           
        
      
        
          - 
            
            
            
            
    #   note.title = 'Battle of Austerlitz'
           
        
      
        
          - 
            
            
            
            
    #   note.text = 'Some text here'
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   user = User.new
           
        
      
        
          - 
            
            
            
            
    #   user.name = 'Napoleon'
           
        
      
        
          - 
            
            
            
            
    #   user.notes = [note]
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   user.serializable_hash
           
        
      
        
          - 
            
            
            
            
    #   # => {"name" => "Napoleon"}
           
        
      
        
          - 
            
            
            
            
    #   user.serializable_hash(include: { notes: { only: 'title' }})
           
        
      
        
          - 
            
            
            
            
    #   # => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
           
        
      
        
          - 
            1
            
            
            
    def serializable_hash(options = nil)
           
        
      
        
          - 
            58
            
            
            
      attribute_names = attributes.keys
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            58
            
            
            
      return serializable_attributes(attribute_names) if options.blank?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            39
            
            
            
      if only = options[:only]
           
        
      
        
          - 
            15
            
            
            
        attribute_names &= Array(only).map(&:to_s)
           
        
      
        
          - 
            24
            
            
            
      elsif except = options[:except]
           
        
      
        
          - 
            7
            
            
            
        attribute_names -= Array(except).map(&:to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            39
            
            
            
      hash = serializable_attributes(attribute_names)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            49
            
            
            
      Array(options[:methods]).each { |m| hash[m.to_s] = send(m) }
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            38
            
            
            
      serializable_add_includes(options) do |association, records, opts|
           
        
      
        
          - 
            16
            
            
            
        hash[association.to_s] = if records.respond_to?(:to_ary)
           
        
      
        
          - 
            28
            
            
            
          records.to_ary.map { |a| a.serializable_hash(opts) }
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            5
            
            
            
          records.serializable_hash(opts)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            38
            
            
            
      hash
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            
            
            
            
      # Hook method defining how an attribute value should be retrieved for
           
        
      
        
          - 
            
            
            
            
      # serialization. By default this is assumed to be an instance named after
           
        
      
        
          - 
            
            
            
            
      # the attribute. Override this method in subclasses should you need to
           
        
      
        
          - 
            
            
            
            
      # retrieve the value for a given attribute differently:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class MyClass
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Serialization
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def initialize(data = {})
           
        
      
        
          - 
            
            
            
            
      #       @data = data
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def read_attribute_for_serialization(key)
           
        
      
        
          - 
            
            
            
            
      #       @data[key]
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            1
            
            
            
      alias :read_attribute_for_serialization :send
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serializable_attributes(attribute_names)
           
        
      
        
          - 
            221
            
            
            
        attribute_names.index_with { |n| read_attribute_for_serialization(n) }
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Add associations specified via the <tt>:include</tt> option.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Expects a block that takes as arguments:
           
        
      
        
          - 
            
            
            
            
      #   +association+ - name of the association
           
        
      
        
          - 
            
            
            
            
      #   +records+     - the association record(s) to be serialized
           
        
      
        
          - 
            
            
            
            
      #   +opts+        - options for the association records
           
        
      
        
          - 
            1
            
            
            
      def serializable_add_includes(options = {}) #:nodoc:
           
        
      
        
          - 
            38
            
            
            
        return unless includes = options[:include]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            13
            
            
            
        unless includes.is_a?(Hash)
           
        
      
        
          - 
            20
            
            
            
          includes = Hash[Array(includes).flat_map { |n| n.is_a?(Hash) ? n.to_a : [[n, {}]] }]
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            13
            
            
            
        includes.each do |association, opts|
           
        
      
        
          - 
            16
            
            
            
          if records = send(association)
           
        
      
        
          - 
            16
            
            
            
            yield association, records, opts
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/json"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Serializers
           
        
      
        
          - 
            
            
            
            
    # == Active \Model \JSON \Serializer
           
        
      
        
          - 
            1
            
            
            
    module JSON
           
        
      
        
          - 
            1
            
            
            
      extend ActiveSupport::Concern
           
        
      
        
          - 
            1
            
            
            
      include ActiveModel::Serialization
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      included do
           
        
      
        
          - 
            1
            
            
            
        extend ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        class_attribute :include_root_in_json, instance_writer: false, default: false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns a hash representing the model. Some configuration can be
           
        
      
        
          - 
            
            
            
            
      # passed through +options+.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The option <tt>include_root_in_json</tt> controls the top-level behavior
           
        
      
        
          - 
            
            
            
            
      # of +as_json+. If +true+, +as_json+ will emit a single root node named
           
        
      
        
          - 
            
            
            
            
      # after the object's type. The default value for <tt>include_root_in_json</tt>
           
        
      
        
          - 
            
            
            
            
      # option is +false+.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user = User.find(1)
           
        
      
        
          - 
            
            
            
            
      #   user.as_json
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #     "created_at" => "2006-08-01T17:27:133.000Z", "awesome" => true}
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   ActiveRecord::Base.include_root_in_json = true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json
           
        
      
        
          - 
            
            
            
            
      #   # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #                  "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true } }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # This behavior can also be achieved by setting the <tt>:root</tt> option
           
        
      
        
          - 
            
            
            
            
      # to +true+ as in:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user = User.find(1)
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(root: true)
           
        
      
        
          - 
            
            
            
            
      #   # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #                  "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true } }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If you prefer, <tt>:root</tt> may also be set to a custom string key instead as in:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user = User.find(1)
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(root: "author")
           
        
      
        
          - 
            
            
            
            
      #   # => { "author" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #                  "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true } }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Without any +options+, the returned Hash will include all the model's
           
        
      
        
          - 
            
            
            
            
      # attributes.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user = User.find(1)
           
        
      
        
          - 
            
            
            
            
      #   user.as_json
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #      "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true}
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit
           
        
      
        
          - 
            
            
            
            
      # the attributes included, and work similar to the +attributes+ method.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(only: [:id, :name])
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi" }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(except: [:id, :created_at, :age])
           
        
      
        
          - 
            
            
            
            
      #   # => { "name" => "Konata Izumi", "awesome" => true }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # To include the result of some method calls on the model use <tt>:methods</tt>:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(methods: :permalink)
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #      "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
           
        
      
        
          - 
            
            
            
            
      #   #      "permalink" => "1-konata-izumi" }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # To include associations use <tt>:include</tt>:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(include: :posts)
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #      "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
           
        
      
        
          - 
            
            
            
            
      #   #      "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
           
        
      
        
          - 
            
            
            
            
      #   #                   { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Second level and higher order associations work as well:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   user.as_json(include: { posts: {
           
        
      
        
          - 
            
            
            
            
      #                              include: { comments: {
           
        
      
        
          - 
            
            
            
            
      #                                             only: :body } },
           
        
      
        
          - 
            
            
            
            
      #                              only: :title } })
           
        
      
        
          - 
            
            
            
            
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
           
        
      
        
          - 
            
            
            
            
      #   #      "created_at" => "2006-08-01T17:27:13.000Z", "awesome" => true,
           
        
      
        
          - 
            
            
            
            
      #   #      "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
           
        
      
        
          - 
            
            
            
            
      #   #                     "title" => "Welcome to the weblog" },
           
        
      
        
          - 
            
            
            
            
      #   #                   { "comments" => [ { "body" => "Don't think too hard" } ],
           
        
      
        
          - 
            
            
            
            
      #   #                     "title" => "So I was thinking" } ] }
           
        
      
        
          - 
            1
            
            
            
      def as_json(options = nil)
           
        
      
        
          - 
            16
            
            
            
        root = if options && options.key?(:root)
           
        
      
        
          - 
            4
            
            
            
          options[:root]
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            12
            
            
            
          include_root_in_json
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            16
            
            
            
        hash = serializable_hash(options).as_json
           
        
      
        
          - 
            16
            
            
            
        if root
           
        
      
        
          - 
            5
            
            
            
          root = model_name.element if root == true
           
        
      
        
          - 
            5
            
            
            
          { root => hash }
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            11
            
            
            
          hash
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Sets the model +attributes+ from a JSON string. Returns +self+.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Serializers::JSON
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name, :age, :awesome
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attributes=(hash)
           
        
      
        
          - 
            
            
            
            
      #       hash.each do |key, value|
           
        
      
        
          - 
            
            
            
            
      #         send("#{key}=", value)
           
        
      
        
          - 
            
            
            
            
      #       end
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def attributes
           
        
      
        
          - 
            
            
            
            
      #       instance_values
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   json = { name: 'bob', age: 22, awesome:true }.to_json
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
           
        
      
        
          - 
            
            
            
            
      #   person.name            # => "bob"
           
        
      
        
          - 
            
            
            
            
      #   person.age             # => 22
           
        
      
        
          - 
            
            
            
            
      #   person.awesome         # => true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The default value for +include_root+ is +false+. You can change it to
           
        
      
        
          - 
            
            
            
            
      # +true+ if the given JSON string includes a single root node.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   json = { person: { name: 'bob', age: 22, awesome:true } }.to_json
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.from_json(json, true) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
           
        
      
        
          - 
            
            
            
            
      #   person.name                  # => "bob"
           
        
      
        
          - 
            
            
            
            
      #   person.age                   # => 22
           
        
      
        
          - 
            
            
            
            
      #   person.awesome               # => true
           
        
      
        
          - 
            1
            
            
            
      def from_json(json, include_root = include_root_in_json)
           
        
      
        
          - 
            3
            
            
            
        hash = ActiveSupport::JSON.decode(json)
           
        
      
        
          - 
            3
            
            
            
        hash = hash.values.first if include_root
           
        
      
        
          - 
            3
            
            
            
        self.attributes = hash
           
        
      
        
          - 
            3
            
            
            
        self
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Translation
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides integration between your object and the Rails internationalization
           
        
      
        
          - 
            
            
            
            
  # (i18n) framework.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class TranslatedPerson
           
        
      
        
          - 
            
            
            
            
  #     extend ActiveModel::Translation
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   TranslatedPerson.human_attribute_name('my_attribute')
           
        
      
        
          - 
            
            
            
            
  #   # => "My attribute"
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # This also provides the required class methods for hooking into the
           
        
      
        
          - 
            
            
            
            
  # Rails internationalization API, including being able to define a
           
        
      
        
          - 
            
            
            
            
  # class based +i18n_scope+ and +lookup_ancestors+ to find translations in
           
        
      
        
          - 
            
            
            
            
  # parent classes.
           
        
      
        
          - 
            1
            
            
            
  module Translation
           
        
      
        
          - 
            1
            
            
            
    include ActiveModel::Naming
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup.
           
        
      
        
          - 
            1
            
            
            
    def i18n_scope
           
        
      
        
          - 
            1636
            
            
            
      :activemodel
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # When localizing a string, it goes through the lookup returned by this
           
        
      
        
          - 
            
            
            
            
    # method, which is used in ActiveModel::Name#human,
           
        
      
        
          - 
            
            
            
            
    # ActiveModel::Errors#full_messages and
           
        
      
        
          - 
            
            
            
            
    # ActiveModel::Translation#human_attribute_name.
           
        
      
        
          - 
            1
            
            
            
    def lookup_ancestors
           
        
      
        
          - 
            23163
            
            
            
      ancestors.select { |x| x.respond_to?(:model_name) }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Transforms attribute names into a more human format, such as "First name"
           
        
      
        
          - 
            
            
            
            
    # instead of "first_name".
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   Person.human_attribute_name("first_name") # => "First name"
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Specify +options+ with additional translating options.
           
        
      
        
          - 
            1
            
            
            
    def human_attribute_name(attribute, options = {})
           
        
      
        
          - 
            586
            
            
            
      options   = { count: 1 }.merge!(options)
           
        
      
        
          - 
            586
            
            
            
      parts     = attribute.to_s.split(".")
           
        
      
        
          - 
            586
            
            
            
      attribute = parts.pop
           
        
      
        
          - 
            586
            
            
            
      namespace = parts.join("/") unless parts.empty?
           
        
      
        
          - 
            586
            
            
            
      attributes_scope = "#{i18n_scope}.attributes"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            586
            
            
            
      if namespace
           
        
      
        
          - 
            19
            
            
            
        defaults = lookup_ancestors.map do |klass|
           
        
      
        
          - 
            34
            
            
            
          :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            19
            
            
            
        defaults << :"#{attributes_scope}.#{namespace}.#{attribute}"
           
        
      
        
          - 
            
            
            
            
      else
           
        
      
        
          - 
            567
            
            
            
        defaults = lookup_ancestors.map do |klass|
           
        
      
        
          - 
            641
            
            
            
          :"#{attributes_scope}.#{klass.model_name.i18n_key}.#{attribute}"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            586
            
            
            
      defaults << :"attributes.#{attribute}"
           
        
      
        
          - 
            586
            
            
            
      defaults << options.delete(:default) if options[:default]
           
        
      
        
          - 
            586
            
            
            
      defaults << attribute.humanize
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            586
            
            
            
      options[:default] = defaults
           
        
      
        
          - 
            586
            
            
            
      I18n.translate(defaults.shift, **options)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/value"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/big_integer"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/binary"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/boolean"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/date"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/date_time"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/decimal"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/float"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/immutable_string"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/integer"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/string"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/time"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/registry"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    @registry = Registry.new
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    class << self
           
        
      
        
          - 
            1
            
            
            
      attr_accessor :registry # :nodoc:
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Add a new type to the registry, allowing it to be gotten through ActiveModel::Type#lookup
           
        
      
        
          - 
            1
            
            
            
      def register(type_name, klass = nil, **options, &block)
           
        
      
        
          - 
            11
            
            
            
        registry.register(type_name, klass, **options, &block)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def lookup(*args, **kwargs) # :nodoc:
           
        
      
        
          - 
            10
            
            
            
        registry.lookup(*args, **kwargs)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def default_value # :nodoc:
           
        
      
        
          - 
            13
            
            
            
        @default_value ||= Value.new
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    register(:big_integer, Type::BigInteger)
           
        
      
        
          - 
            1
            
            
            
    register(:binary, Type::Binary)
           
        
      
        
          - 
            1
            
            
            
    register(:boolean, Type::Boolean)
           
        
      
        
          - 
            1
            
            
            
    register(:date, Type::Date)
           
        
      
        
          - 
            1
            
            
            
    register(:datetime, Type::DateTime)
           
        
      
        
          - 
            1
            
            
            
    register(:decimal, Type::Decimal)
           
        
      
        
          - 
            1
            
            
            
    register(:float, Type::Float)
           
        
      
        
          - 
            1
            
            
            
    register(:immutable_string, Type::ImmutableString)
           
        
      
        
          - 
            1
            
            
            
    register(:integer, Type::Integer)
           
        
      
        
          - 
            1
            
            
            
    register(:string, Type::String)
           
        
      
        
          - 
            1
            
            
            
    register(:time, Type::Time)
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/integer"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class BigInteger < Integer # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def max_value
           
        
      
        
          - 
            6
            
            
            
          ::Float::INFINITY
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Binary < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :binary
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def binary?
           
        
      
        
          - 
            
            
            
            
        true
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def cast(value)
           
        
      
        
          - 
            3
            
            
            
        if value.is_a?(Data)
           
        
      
        
          - 
            
            
            
            
          value.to_s
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            3
            
            
            
          super
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serialize(value)
           
        
      
        
          - 
            
            
            
            
        return if value.nil?
           
        
      
        
          - 
            
            
            
            
        Data.new(super)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def changed_in_place?(raw_old_value, value)
           
        
      
        
          - 
            
            
            
            
        old_value = deserialize(raw_old_value)
           
        
      
        
          - 
            
            
            
            
        old_value != value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      class Data # :nodoc:
           
        
      
        
          - 
            1
            
            
            
        def initialize(value)
           
        
      
        
          - 
            
            
            
            
          @value = value.to_s
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def to_s
           
        
      
        
          - 
            
            
            
            
          @value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            1
            
            
            
        alias_method :to_str, :to_s
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def hex
           
        
      
        
          - 
            
            
            
            
          @value.unpack1("H*")
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def ==(other)
           
        
      
        
          - 
            
            
            
            
          other == to_s || super
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            
            
            
            
    # == 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+
           
        
      
        
          - 
            1
            
            
            
    class Boolean < Value
           
        
      
        
          - 
            1
            
            
            
      FALSE_VALUES = [
           
        
      
        
          - 
            
            
            
            
        false, 0,
           
        
      
        
          - 
            
            
            
            
        "0", :"0",
           
        
      
        
          - 
            
            
            
            
        "f", :f,
           
        
      
        
          - 
            
            
            
            
        "F", :F,
           
        
      
        
          - 
            
            
            
            
        "false", :false,
           
        
      
        
          - 
            
            
            
            
        "FALSE", :FALSE,
           
        
      
        
          - 
            
            
            
            
        "off", :off,
           
        
      
        
          - 
            
            
            
            
        "OFF", :OFF,
           
        
      
        
          - 
            
            
            
            
      ].to_set.freeze
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type # :nodoc:
           
        
      
        
          - 
            
            
            
            
        :boolean
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serialize(value) # :nodoc:
           
        
      
        
          - 
            
            
            
            
        cast(value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            40
            
            
            
          if value == ""
           
        
      
        
          - 
            
            
            
            
            nil
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            39
            
            
            
            !FALSE_VALUES.include?(value)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Date < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Timezone
           
        
      
        
          - 
            1
            
            
            
      include Helpers::AcceptsMultiparameterTime.new
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :date
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type_cast_for_schema(value)
           
        
      
        
          - 
            
            
            
            
        value.to_s(:db).inspect
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            8
            
            
            
          if value.is_a?(::String)
           
        
      
        
          - 
            4
            
            
            
            return if value.empty?
           
        
      
        
          - 
            3
            
            
            
            fast_string_to_date(value) || fallback_string_to_date(value)
           
        
      
        
          - 
            4
            
            
            
          elsif value.respond_to?(:to_date)
           
        
      
        
          - 
            4
            
            
            
            value.to_date
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            
            
            
            
            value
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
           
        
      
        
          - 
            1
            
            
            
        def fast_string_to_date(string)
           
        
      
        
          - 
            3
            
            
            
          if string =~ ISO_DATE
           
        
      
        
          - 
            1
            
            
            
            new_date $1.to_i, $2.to_i, $3.to_i
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def fallback_string_to_date(string)
           
        
      
        
          - 
            2
            
            
            
          new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def new_date(year, mon, mday)
           
        
      
        
          - 
            5
            
            
            
          unless year.nil? || (year == 0 && mon == 0 && mday == 0)
           
        
      
        
          - 
            3
            
            
            
            ::Date.new(year, mon, mday) rescue nil
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def value_from_multiparameter_assignment(*)
           
        
      
        
          - 
            2
            
            
            
          time = super
           
        
      
        
          - 
            2
            
            
            
          time && new_date(time.year, time.mon, time.mday)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class DateTime < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Timezone
           
        
      
        
          - 
            1
            
            
            
      include Helpers::TimeValue
           
        
      
        
          - 
            1
            
            
            
      include Helpers::AcceptsMultiparameterTime.new(
           
        
      
        
          - 
            
            
            
            
        defaults: { 4 => 0, 5 => 0 }
           
        
      
        
          - 
            
            
            
            
      )
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :datetime
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            6
            
            
            
          return apply_seconds_precision(value) unless value.is_a?(::String)
           
        
      
        
          - 
            6
            
            
            
          return if value.empty?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            5
            
            
            
          fast_string_to_time(value) || fallback_string_to_time(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # '0.123456' -> 123456
           
        
      
        
          - 
            
            
            
            
        # '1.123456' -> 123456
           
        
      
        
          - 
            1
            
            
            
        def microseconds(time)
           
        
      
        
          - 
            4
            
            
            
          time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def fallback_string_to_time(string)
           
        
      
        
          - 
            4
            
            
            
          time_hash = ::Date._parse(string)
           
        
      
        
          - 
            4
            
            
            
          time_hash[:sec_fraction] = microseconds(time_hash)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
          new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def value_from_multiparameter_assignment(values_hash)
           
        
      
        
          - 
            8
            
            
            
          missing_parameters = [1, 2, 3].delete_if { |key| values_hash.key?(key) }
           
        
      
        
          - 
            2
            
            
            
          unless missing_parameters.empty?
           
        
      
        
          - 
            1
            
            
            
            raise ArgumentError, "Provided hash #{values_hash} doesn't contain necessary keys: #{missing_parameters}"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            1
            
            
            
          super
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "bigdecimal/util"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Decimal < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Numeric
           
        
      
        
          - 
            1
            
            
            
      BIGDECIMAL_PRECISION = 18
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :decimal
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type_cast_for_schema(value)
           
        
      
        
          - 
            
            
            
            
        value.to_s.inspect
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            17
            
            
            
          casted_value = \
           
        
      
        
          - 
            
            
            
            
            case value
           
        
      
        
          - 
            
            
            
            
            when ::Float
           
        
      
        
          - 
            5
            
            
            
              convert_float_to_big_decimal(value)
           
        
      
        
          - 
            
            
            
            
            when ::Numeric
           
        
      
        
          - 
            4
            
            
            
              BigDecimal(value, precision || BIGDECIMAL_PRECISION)
           
        
      
        
          - 
            
            
            
            
            when ::String
           
        
      
        
          - 
            6
            
            
            
              begin
           
        
      
        
          - 
            6
            
            
            
                value.to_d
           
        
      
        
          - 
            
            
            
            
              rescue ArgumentError
           
        
      
        
          - 
            
            
            
            
                BigDecimal(0)
           
        
      
        
          - 
            
            
            
            
              end
           
        
      
        
          - 
            
            
            
            
            else
           
        
      
        
          - 
            2
            
            
            
              if value.respond_to?(:to_d)
           
        
      
        
          - 
            1
            
            
            
                value.to_d
           
        
      
        
          - 
            
            
            
            
              else
           
        
      
        
          - 
            1
            
            
            
                cast_value(value.to_s)
           
        
      
        
          - 
            
            
            
            
              end
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            17
            
            
            
          apply_scale(casted_value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def convert_float_to_big_decimal(value)
           
        
      
        
          - 
            5
            
            
            
          if precision
           
        
      
        
          - 
            2
            
            
            
            BigDecimal(apply_scale(value), float_precision)
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            3
            
            
            
            value.to_d
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def float_precision
           
        
      
        
          - 
            2
            
            
            
          if precision.to_i > ::Float::DIG + 1
           
        
      
        
          - 
            1
            
            
            
            ::Float::DIG + 1
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            1
            
            
            
            precision.to_i
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def apply_scale(value)
           
        
      
        
          - 
            19
            
            
            
          if scale
           
        
      
        
          - 
            4
            
            
            
            value.round(scale)
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            15
            
            
            
            value
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/object/try"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Float < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Numeric
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :float
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      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
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            9
            
            
            
          case value
           
        
      
        
          - 
            
            
            
            
          when ::Float then value
           
        
      
        
          - 
            
            
            
            
          when "Infinity" then ::Float::INFINITY
           
        
      
        
          - 
            
            
            
            
          when "-Infinity" then -::Float::INFINITY
           
        
      
        
          - 
            
            
            
            
          when "NaN" then ::Float::NAN
           
        
      
        
          - 
            9
            
            
            
          else value.to_f
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers/accepts_multiparameter_time"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers/numeric"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers/mutable"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers/time_value"
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/helpers/timezone"
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    module Helpers # :nodoc: all
           
        
      
        
          - 
            1
            
            
            
      class AcceptsMultiparameterTime < Module
           
        
      
        
          - 
            1
            
            
            
        module InstanceMethods
           
        
      
        
          - 
            1
            
            
            
          def serialize(value)
           
        
      
        
          - 
            
            
            
            
            super(cast(value))
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def cast(value)
           
        
      
        
          - 
            27
            
            
            
            if value.is_a?(Hash)
           
        
      
        
          - 
            5
            
            
            
              value_from_multiparameter_assignment(value)
           
        
      
        
          - 
            
            
            
            
            else
           
        
      
        
          - 
            22
            
            
            
              super(value)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def assert_valid_value(value)
           
        
      
        
          - 
            
            
            
            
            if value.is_a?(Hash)
           
        
      
        
          - 
            
            
            
            
              value_from_multiparameter_assignment(value)
           
        
      
        
          - 
            
            
            
            
            else
           
        
      
        
          - 
            
            
            
            
              super(value)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def value_constructed_by_mass_assignment?(value)
           
        
      
        
          - 
            
            
            
            
            value.is_a?(Hash)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def initialize(defaults: {})
           
        
      
        
          - 
            3
            
            
            
          include InstanceMethods
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
          define_method(:value_from_multiparameter_assignment) do |values_hash|
           
        
      
        
          - 
            4
            
            
            
            defaults.each do |k, v|
           
        
      
        
          - 
            7
            
            
            
              values_hash[k] ||= v
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            4
            
            
            
            return unless values_hash[1] && values_hash[2] && values_hash[3]
           
        
      
        
          - 
            4
            
            
            
            values = values_hash.sort.map!(&:last)
           
        
      
        
          - 
            4
            
            
            
            ::Time.send(default_timezone, *values)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            3
            
            
            
          private :value_from_multiparameter_assignment
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    module Helpers # :nodoc: all
           
        
      
        
          - 
            1
            
            
            
      module Mutable
           
        
      
        
          - 
            1
            
            
            
        def cast(value)
           
        
      
        
          - 
            
            
            
            
          deserialize(serialize(value))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # +raw_old_value+ will be the `_before_type_cast` version of the
           
        
      
        
          - 
            
            
            
            
        # value (likely a string). +new_value+ will be the current, type
           
        
      
        
          - 
            
            
            
            
        # cast value.
           
        
      
        
          - 
            1
            
            
            
        def changed_in_place?(raw_old_value, new_value)
           
        
      
        
          - 
            
            
            
            
          raw_old_value != serialize(new_value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    module Helpers # :nodoc: all
           
        
      
        
          - 
            1
            
            
            
      module Numeric
           
        
      
        
          - 
            1
            
            
            
        def serialize(value)
           
        
      
        
          - 
            34
            
            
            
          cast(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def cast(value)
           
        
      
        
          - 
            
            
            
            
          # Checks whether the value is numeric. Spaceship operator
           
        
      
        
          - 
            
            
            
            
          # will return nil if value is not numeric.
           
        
      
        
          - 
            93
            
            
            
          value = if value <=> 0
           
        
      
        
          - 
            37
            
            
            
            value
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            56
            
            
            
            case value
           
        
      
        
          - 
            2
            
            
            
            when true then 1
           
        
      
        
          - 
            2
            
            
            
            when false then 0
           
        
      
        
          - 
            52
            
            
            
            else value.presence
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            93
            
            
            
          super(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc:
           
        
      
        
          - 
            28
            
            
            
          super || number_to_non_number?(old_value, new_value_before_type_cast)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        private
           
        
      
        
          - 
            1
            
            
            
          def number_to_non_number?(old_value, new_value_before_type_cast)
           
        
      
        
          - 
            21
            
            
            
            old_value != nil && non_numeric_string?(new_value_before_type_cast.to_s)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          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.
           
        
      
        
          - 
            24
            
            
            
            !NUMERIC_REGEX.match?(value)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          NUMERIC_REGEX = /\A\s*[+-]?\d/
           
        
      
        
          - 
            1
            
            
            
          private_constant :NUMERIC_REGEX
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/string/zones"
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/time/zones"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    module Helpers # :nodoc: all
           
        
      
        
          - 
            1
            
            
            
      module TimeValue
           
        
      
        
          - 
            1
            
            
            
        def serialize(value)
           
        
      
        
          - 
            
            
            
            
          value = apply_seconds_precision(value)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          if value.acts_like?(:time)
           
        
      
        
          - 
            
            
            
            
            if is_utc?
           
        
      
        
          - 
            
            
            
            
              value = value.getutc if value.respond_to?(:getutc) && !value.utc?
           
        
      
        
          - 
            
            
            
            
            else
           
        
      
        
          - 
            
            
            
            
              value = value.getlocal if value.respond_to?(:getlocal)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def apply_seconds_precision(value)
           
        
      
        
          - 
            
            
            
            
          return value unless precision && value.respond_to?(:nsec)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          number_of_insignificant_digits = 9 - precision
           
        
      
        
          - 
            
            
            
            
          round_power = 10**number_of_insignificant_digits
           
        
      
        
          - 
            
            
            
            
          rounded_off_nsec = value.nsec % round_power
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
          if rounded_off_nsec > 0
           
        
      
        
          - 
            
            
            
            
            value.change(nsec: value.nsec - rounded_off_nsec)
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            
            
            
            
            value
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def type_cast_for_schema(value)
           
        
      
        
          - 
            
            
            
            
          value.to_s(:db).inspect
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def user_input_in_time_zone(value)
           
        
      
        
          - 
            2
            
            
            
          value.in_time_zone
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        private
           
        
      
        
          - 
            1
            
            
            
          def new_time(year, mon, mday, hour, min, sec, microsec, offset = nil)
           
        
      
        
          - 
            
            
            
            
            # Treat 0000-00-00 00:00:00 as nil.
           
        
      
        
          - 
            8
            
            
            
            return if year.nil? || (year == 0 && mon == 0 && mday == 0)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            6
            
            
            
            if offset
           
        
      
        
          - 
            4
            
            
            
              time = ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil
           
        
      
        
          - 
            4
            
            
            
              return unless time
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
              time -= offset unless offset == 0
           
        
      
        
          - 
            4
            
            
            
              is_utc? ? time : time.getlocal
           
        
      
        
          - 
            2
            
            
            
            elsif is_utc?
           
        
      
        
          - 
            2
            
            
            
              ::Time.utc(year, mon, mday, hour, min, sec, microsec) rescue nil
           
        
      
        
          - 
            
            
            
            
            else
           
        
      
        
          - 
            
            
            
            
              ::Time.local(year, mon, mday, hour, min, sec, microsec) rescue nil
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          ISO_DATETIME = /
           
        
      
        
          - 
            
            
            
            
            \A
           
        
      
        
          - 
            
            
            
            
            (\d{4})-(\d\d)-(\d\d)(?:T|\s)            # 2020-06-20T
           
        
      
        
          - 
            
            
            
            
            (\d\d):(\d\d):(\d\d)(?:\.(\d{1,6})\d*)?  # 10:20:30.123456
           
        
      
        
          - 
            
            
            
            
            (?:(Z(?=\z)|[+-]\d\d)(?::?(\d\d))?)?     # +09:00
           
        
      
        
          - 
            
            
            
            
            \z
           
        
      
        
          - 
            
            
            
            
          /x
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def fast_string_to_time(string)
           
        
      
        
          - 
            9
            
            
            
            return unless ISO_DATETIME =~ string
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
            usec = $7.to_i
           
        
      
        
          - 
            3
            
            
            
            usec_len = $7&.length
           
        
      
        
          - 
            3
            
            
            
            if usec_len&.< 6
           
        
      
        
          - 
            
            
            
            
              usec *= 10 ** (6 - usec_len)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
            if $8
           
        
      
        
          - 
            1
            
            
            
              offset = $8 == "Z" ? 0 : $8.to_i * 3600 + $9.to_i * 60
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
            new_time($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, usec, offset)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/time/zones"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    module Helpers # :nodoc: all
           
        
      
        
          - 
            1
            
            
            
      module Timezone
           
        
      
        
          - 
            1
            
            
            
        def is_utc?
           
        
      
        
          - 
            10
            
            
            
          ::Time.zone_default.nil? || ::Time.zone_default.match?("UTC")
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def default_timezone
           
        
      
        
          - 
            4
            
            
            
          is_utc? ? :utc : :local
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class ImmutableString < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def initialize(**args)
           
        
      
        
          - 
            17
            
            
            
        @true  = -(args.delete(:true)&.to_s  || "t")
           
        
      
        
          - 
            17
            
            
            
        @false = -(args.delete(:false)&.to_s || "f")
           
        
      
        
          - 
            17
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :string
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serialize(value)
           
        
      
        
          - 
            36
            
            
            
        case value
           
        
      
        
          - 
            
            
            
            
        when ::Numeric, ::Symbol, ActiveSupport::Duration then value.to_s
           
        
      
        
          - 
            
            
            
            
        when true then @true
           
        
      
        
          - 
            
            
            
            
        when false then @false
           
        
      
        
          - 
            36
            
            
            
        else super
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            3
            
            
            
          case value
           
        
      
        
          - 
            
            
            
            
          when true then @true
           
        
      
        
          - 
            
            
            
            
          when false then @false
           
        
      
        
          - 
            3
            
            
            
          else value.to_s.freeze
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Integer < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Numeric
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Column storage size in bytes.
           
        
      
        
          - 
            
            
            
            
      # 4 bytes means an integer as opposed to smallint etc.
           
        
      
        
          - 
            1
            
            
            
      DEFAULT_LIMIT = 4
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize(**)
           
        
      
        
          - 
            55
            
            
            
        super
           
        
      
        
          - 
            55
            
            
            
        @range = min_value...max_value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :integer
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def deserialize(value)
           
        
      
        
          - 
            20
            
            
            
        return if value.blank?
           
        
      
        
          - 
            18
            
            
            
        value.to_i
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serialize(value)
           
        
      
        
          - 
            36
            
            
            
        return if value.is_a?(::String) && non_numeric_string?(value)
           
        
      
        
          - 
            34
            
            
            
        ensure_in_range(super)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def serializable?(value)
           
        
      
        
          - 
            
            
            
            
        cast_value = cast(value)
           
        
      
        
          - 
            
            
            
            
        in_range?(cast_value) && super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        attr_reader :range
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def in_range?(value)
           
        
      
        
          - 
            34
            
            
            
          !value || range.member?(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            51
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            6
            
            
            
          value.to_i rescue nil
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def ensure_in_range(value)
           
        
      
        
          - 
            34
            
            
            
          unless in_range?(value)
           
        
      
        
          - 
            6
            
            
            
            raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            28
            
            
            
          value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def max_value
           
        
      
        
          - 
            104
            
            
            
          1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def min_value
           
        
      
        
          - 
            55
            
            
            
          -max_value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def _limit
           
        
      
        
          - 
            110
            
            
            
          limit || DEFAULT_LIMIT
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # :stopdoc:
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Registry
           
        
      
        
          - 
            1
            
            
            
      def initialize
           
        
      
        
          - 
            4
            
            
            
        @registrations = []
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize_dup(other)
           
        
      
        
          - 
            
            
            
            
        @registrations = @registrations.dup
           
        
      
        
          - 
            
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def register(type_name, klass = nil, **options, &block)
           
        
      
        
          - 
            16
            
            
            
        unless block_given?
           
        
      
        
          - 
            25
            
            
            
          block = proc { |_, *args| klass.new(*args) }
           
        
      
        
          - 
            13
            
            
            
          block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            16
            
            
            
        registrations << registration_klass.new(type_name, block, **options)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def lookup(symbol, *args, **kwargs)
           
        
      
        
          - 
            17
            
            
            
        registration = find_registration(symbol, *args, **kwargs)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            17
            
            
            
        if registration
           
        
      
        
          - 
            16
            
            
            
          registration.call(self, symbol, *args, **kwargs)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            1
            
            
            
          raise ArgumentError, "Unknown type #{symbol.inspect}"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        attr_reader :registrations
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def registration_klass
           
        
      
        
          - 
            16
            
            
            
          Registration
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def find_registration(symbol, *args, **kwargs)
           
        
      
        
          - 
            108
            
            
            
          registrations.find { |r| r.matches?(symbol, *args, **kwargs) }
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    class Registration
           
        
      
        
          - 
            
            
            
            
      # Options must be taken because of https://bugs.ruby-lang.org/issues/10856
           
        
      
        
          - 
            1
            
            
            
      def initialize(name, block, **)
           
        
      
        
          - 
            16
            
            
            
        @name = name
           
        
      
        
          - 
            16
            
            
            
        @block = block
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def call(_registry, *args, **kwargs)
           
        
      
        
          - 
            16
            
            
            
        if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
           
        
      
        
          - 
            1
            
            
            
          block.call(*args, **kwargs)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            15
            
            
            
          block.call(*args)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def matches?(type_name, *args, **kwargs)
           
        
      
        
          - 
            91
            
            
            
        type_name == name
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        attr_reader :name, :block
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
  # :startdoc:
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/type/immutable_string"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class String < ImmutableString # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def changed_in_place?(raw_old_value, new_value)
           
        
      
        
          - 
            6
            
            
            
        if new_value.is_a?(::String)
           
        
      
        
          - 
            5
            
            
            
          raw_old_value != new_value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def to_immutable_string
           
        
      
        
          - 
            
            
            
            
        ImmutableString.new(
           
        
      
        
          - 
            
            
            
            
          true: @true,
           
        
      
        
          - 
            
            
            
            
          false: @false,
           
        
      
        
          - 
            
            
            
            
          limit: limit,
           
        
      
        
          - 
            
            
            
            
          precision: precision,
           
        
      
        
          - 
            
            
            
            
          scale: scale,
           
        
      
        
          - 
            
            
            
            
        )
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            78
            
            
            
          case value
           
        
      
        
          - 
            74
            
            
            
          when ::String then ::String.new(value)
           
        
      
        
          - 
            1
            
            
            
          when true then @true
           
        
      
        
          - 
            1
            
            
            
          when false then @false
           
        
      
        
          - 
            2
            
            
            
          else value.to_s
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Time < Value # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Helpers::Timezone
           
        
      
        
          - 
            1
            
            
            
      include Helpers::TimeValue
           
        
      
        
          - 
            1
            
            
            
      include Helpers::AcceptsMultiparameterTime.new(
           
        
      
        
          - 
            
            
            
            
        defaults: { 1 => 2000, 2 => 1, 3 => 1, 4 => 0, 5 => 0 }
           
        
      
        
          - 
            
            
            
            
      )
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type
           
        
      
        
          - 
            
            
            
            
        :time
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def user_input_in_time_zone(value)
           
        
      
        
          - 
            5
            
            
            
        return unless value.present?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            3
            
            
            
        case value
           
        
      
        
          - 
            
            
            
            
        when ::String
           
        
      
        
          - 
            3
            
            
            
          value = "2000-01-01 #{value}"
           
        
      
        
          - 
            3
            
            
            
          time_hash = ::Date._parse(value)
           
        
      
        
          - 
            3
            
            
            
          return if time_hash[:hour].nil?
           
        
      
        
          - 
            
            
            
            
        when ::Time
           
        
      
        
          - 
            
            
            
            
          value = value.change(year: 2000, day: 1, month: 1)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
        super(value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value)
           
        
      
        
          - 
            5
            
            
            
          return apply_seconds_precision(value) unless value.is_a?(::String)
           
        
      
        
          - 
            5
            
            
            
          return if value.empty?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
          dummy_time_value = value.sub(/\A(\d\d\d\d-\d\d-\d\d |)/, "2000-01-01 ")
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
          fast_string_to_time(dummy_time_value) || begin
           
        
      
        
          - 
            2
            
            
            
            time_hash = ::Date._parse(dummy_time_value)
           
        
      
        
          - 
            2
            
            
            
            return if time_hash[:hour].nil?
           
        
      
        
          - 
            1
            
            
            
            new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Type
           
        
      
        
          - 
            1
            
            
            
    class Value
           
        
      
        
          - 
            1
            
            
            
      attr_reader :precision, :scale, :limit
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize(precision: nil, limit: nil, scale: nil)
           
        
      
        
          - 
            130
            
            
            
        @precision = precision
           
        
      
        
          - 
            130
            
            
            
        @scale = scale
           
        
      
        
          - 
            130
            
            
            
        @limit = limit
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns true if this type can convert +value+ to a type that is usable
           
        
      
        
          - 
            
            
            
            
      # by the database.  For example a boolean type can return +true+ if the
           
        
      
        
          - 
            
            
            
            
      # value parameter is a Ruby boolean, but may return +false+ if the value
           
        
      
        
          - 
            
            
            
            
      # parameter is some other object.
           
        
      
        
          - 
            1
            
            
            
      def serializable?(value)
           
        
      
        
          - 
            
            
            
            
        true
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def type # :nodoc:
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Converts a value from database input to the appropriate ruby type. The
           
        
      
        
          - 
            
            
            
            
      # return value of this method will be returned from
           
        
      
        
          - 
            
            
            
            
      # ActiveRecord::AttributeMethods::Read#read_attribute. The default
           
        
      
        
          - 
            
            
            
            
      # implementation just calls Value#cast.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # +value+ The raw input, as provided from the database.
           
        
      
        
          - 
            1
            
            
            
      def deserialize(value)
           
        
      
        
          - 
            45
            
            
            
        cast(value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Type casts a value from user input (e.g. from a setter). This value may
           
        
      
        
          - 
            
            
            
            
      # be a string from the form builder, or a ruby object passed to a setter.
           
        
      
        
          - 
            
            
            
            
      # There is currently no way to differentiate between which source it came
           
        
      
        
          - 
            
            
            
            
      # from.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The return value of this method will be returned from
           
        
      
        
          - 
            
            
            
            
      # ActiveRecord::AttributeMethods::Read#read_attribute. See also:
           
        
      
        
          - 
            
            
            
            
      # Value#cast_value.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # +value+ The raw input, as provided to the attribute setter.
           
        
      
        
          - 
            1
            
            
            
      def cast(value)
           
        
      
        
          - 
            253
            
            
            
        cast_value(value) unless value.nil?
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Casts a value from the ruby type to a type that the database knows how
           
        
      
        
          - 
            
            
            
            
      # to understand. The returned value from this method should be a
           
        
      
        
          - 
            
            
            
            
      # +String+, +Numeric+, +Date+, +Time+, +Symbol+, +true+, +false+, or
           
        
      
        
          - 
            
            
            
            
      # +nil+.
           
        
      
        
          - 
            1
            
            
            
      def serialize(value)
           
        
      
        
          - 
            36
            
            
            
        value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Type casts a value for schema dumping. This method is private, as we are
           
        
      
        
          - 
            
            
            
            
      # hoping to remove it entirely.
           
        
      
        
          - 
            1
            
            
            
      def type_cast_for_schema(value) # :nodoc:
           
        
      
        
          - 
            
            
            
            
        value.inspect
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # These predicates are not documented, as I need to look further into
           
        
      
        
          - 
            
            
            
            
      # their use, and see if they can be removed entirely.
           
        
      
        
          - 
            1
            
            
            
      def binary? # :nodoc:
           
        
      
        
          - 
            
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Determines whether a value has changed for dirty checking. +old_value+
           
        
      
        
          - 
            
            
            
            
      # and +new_value+ will always be type-cast. Types should not need to
           
        
      
        
          - 
            
            
            
            
      # override this method.
           
        
      
        
          - 
            1
            
            
            
      def changed?(old_value, new_value, _new_value_before_type_cast)
           
        
      
        
          - 
            65
            
            
            
        old_value != new_value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Determines whether the mutable value has been modified since it was
           
        
      
        
          - 
            
            
            
            
      # read. Returns +false+ by default. If your type returns an object
           
        
      
        
          - 
            
            
            
            
      # which could be mutated, you should override this method. You will need
           
        
      
        
          - 
            
            
            
            
      # to either:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # - pass +new_value+ to Value#serialize and compare it to
           
        
      
        
          - 
            
            
            
            
      #   +raw_old_value+
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # or
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # - pass +raw_old_value+ to Value#deserialize and compare it to
           
        
      
        
          - 
            
            
            
            
      #   +new_value+
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # +raw_old_value+ The original value, before being passed to
           
        
      
        
          - 
            
            
            
            
      # +deserialize+.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # +new_value+ The current value, after type casting.
           
        
      
        
          - 
            1
            
            
            
      def changed_in_place?(raw_old_value, new_value)
           
        
      
        
          - 
            3
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def value_constructed_by_mass_assignment?(_value) # :nodoc:
           
        
      
        
          - 
            
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def force_equality?(_value) # :nodoc:
           
        
      
        
          - 
            
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def map(value) # :nodoc:
           
        
      
        
          - 
            
            
            
            
        yield value
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def ==(other)
           
        
      
        
          - 
            13
            
            
            
        self.class == other.class &&
           
        
      
        
          - 
            
            
            
            
          precision == other.precision &&
           
        
      
        
          - 
            
            
            
            
          scale == other.scale &&
           
        
      
        
          - 
            
            
            
            
          limit == other.limit
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            1
            
            
            
      alias eql? ==
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def hash
           
        
      
        
          - 
            
            
            
            
        [self.class, precision, scale, limit].hash
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def assert_valid_value(_)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      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+.
           
        
      
        
          - 
            1
            
            
            
        def cast_value(value) # :doc:
           
        
      
        
          - 
            11
            
            
            
          value
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/array/extract_options"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Validations
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Provides a full validation framework to your objects.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A minimal implementation could be:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :first_name, :last_name
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     validates_each :first_name, :last_name do |record, attr, value|
           
        
      
        
          - 
            
            
            
            
  #       record.errors.add attr, "starts with z." if value.start_with?("z")
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Which provides you with the full standard validation stack that you
           
        
      
        
          - 
            
            
            
            
  # know from Active Record:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person = Person.new
           
        
      
        
          - 
            
            
            
            
  #   person.valid?                   # => true
           
        
      
        
          - 
            
            
            
            
  #   person.invalid?                 # => false
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   person.first_name = 'zoolander'
           
        
      
        
          - 
            
            
            
            
  #   person.valid?                   # => false
           
        
      
        
          - 
            
            
            
            
  #   person.invalid?                 # => true
           
        
      
        
          - 
            
            
            
            
  #   person.errors.messages          # => {first_name:["starts with z."]}
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+
           
        
      
        
          - 
            
            
            
            
  # method to your instances initialized with a new <tt>ActiveModel::Errors</tt>
           
        
      
        
          - 
            
            
            
            
  # object, so there is no need for you to do this manually.
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    extend ActiveSupport::Concern
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    included do
           
        
      
        
          - 
            14
            
            
            
      extend ActiveModel::Naming
           
        
      
        
          - 
            14
            
            
            
      extend ActiveModel::Callbacks
           
        
      
        
          - 
            14
            
            
            
      extend ActiveModel::Translation
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            14
            
            
            
      extend  HelperMethods
           
        
      
        
          - 
            14
            
            
            
      include HelperMethods
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            14
            
            
            
      attr_accessor :validation_context
           
        
      
        
          - 
            14
            
            
            
      private :validation_context=
           
        
      
        
          - 
            14
            
            
            
      define_callbacks :validate, scope: :name
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            367
            
            
            
      class_attribute :_validators, instance_writer: false, default: Hash.new { |h, k| h[k] = [] }
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            
            
            
            
      # Validates each attribute against a block.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :first_name, :last_name
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates_each :first_name, :last_name, allow_blank: true do |record, attr, value|
           
        
      
        
          - 
            
            
            
            
      #       record.errors.add attr, "starts with z." if value.start_with?("z")
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # 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
           
        
      
        
          - 
            
            
            
            
      #   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>)
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
           
        
      
        
          - 
            
            
            
            
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
           
        
      
        
          - 
            
            
            
            
      #   proc or string should return or evaluate to a +true+ or +false+ value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
           
        
      
        
          - 
            
            
            
            
      #   determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
           
        
      
        
          - 
            
            
            
            
      #   method, proc or string should return or evaluate to a +true+ or +false+
           
        
      
        
          - 
            
            
            
            
      #   value.
           
        
      
        
          - 
            1
            
            
            
      def validates_each(*attr_names, &block)
           
        
      
        
          - 
            2
            
            
            
        validates_with BlockValidator, _merge_attributes(attr_names), &block
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      VALID_OPTIONS_FOR_VALIDATE = [:on, :if, :unless, :prepend].freeze # :nodoc:
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Adds a validation method or block to the class. This is useful when
           
        
      
        
          - 
            
            
            
            
      # overriding the +validate+ instance method becomes too unwieldy and
           
        
      
        
          - 
            
            
            
            
      # you're looking for more descriptive declaration of your validations.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # This can be done with a symbol pointing to a method:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Comment
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validate :must_be_friends
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def must_be_friends
           
        
      
        
          - 
            
            
            
            
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # With a block which is passed with the current record to be validated:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Comment
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validate do |comment|
           
        
      
        
          - 
            
            
            
            
      #       comment.must_be_friends
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def must_be_friends
           
        
      
        
          - 
            
            
            
            
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Or with a block where self points to the current record to be validated:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Comment
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validate do
           
        
      
        
          - 
            
            
            
            
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Note that the return value of validation methods is not relevant.
           
        
      
        
          - 
            
            
            
            
      # It's not possible to halt the validate callback chain.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # 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
           
        
      
        
          - 
            
            
            
            
      #   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>)
           
        
      
        
          - 
            
            
            
            
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
           
        
      
        
          - 
            
            
            
            
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
           
        
      
        
          - 
            
            
            
            
      #   proc or string should return or evaluate to a +true+ or +false+ value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
           
        
      
        
          - 
            
            
            
            
      #   determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
           
        
      
        
          - 
            
            
            
            
      #   method, proc or string should return or evaluate to a +true+ or +false+
           
        
      
        
          - 
            
            
            
            
      #   value.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # NOTE: Calling +validate+ multiple times on the same method will overwrite previous definitions.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            1
            
            
            
      def validate(*args, &block)
           
        
      
        
          - 
            372
            
            
            
        options = args.extract_options!
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            739
            
            
            
        if args.all? { |arg| arg.is_a?(Symbol) }
           
        
      
        
          - 
            15
            
            
            
          options.each_key do |k|
           
        
      
        
          - 
            7
            
            
            
            unless VALID_OPTIONS_FOR_VALIDATE.include?(k)
           
        
      
        
          - 
            1
            
            
            
              raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{VALID_OPTIONS_FOR_VALIDATE.map(&:inspect).join(', ')}. Perhaps you meant to call `validates` instead of `validate`?")
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            371
            
            
            
        if options.key?(:on)
           
        
      
        
          - 
            11
            
            
            
          options = options.dup
           
        
      
        
          - 
            11
            
            
            
          options[:on] = Array(options[:on])
           
        
      
        
          - 
            11
            
            
            
          options[:if] = Array(options[:if])
           
        
      
        
          - 
            11
            
            
            
          options[:if].unshift ->(o) {
           
        
      
        
          - 
            38
            
            
            
            !(options[:on] & Array(o.validation_context)).empty?
           
        
      
        
          - 
            
            
            
            
          }
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            371
            
            
            
        set_callback(:validate, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # List all validators that are being used to validate the model using
           
        
      
        
          - 
            
            
            
            
      # +validates_with+ method.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
      #     validates_with OtherValidator, on: :create
           
        
      
        
          - 
            
            
            
            
      #     validates_with StrictValidator, strict: true
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.validators
           
        
      
        
          - 
            
            
            
            
      #   # => [
           
        
      
        
          - 
            
            
            
            
      #   #      #<MyValidator:0x007fbff403e808 @options={}>,
           
        
      
        
          - 
            
            
            
            
      #   #      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
           
        
      
        
          - 
            
            
            
            
      #   #      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
           
        
      
        
          - 
            
            
            
            
      #   #    ]
           
        
      
        
          - 
            1
            
            
            
      def validators
           
        
      
        
          - 
            2
            
            
            
        _validators.values.flatten.uniq
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Clears all of the validators and validations.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Note that this will clear anything that is being used to validate
           
        
      
        
          - 
            
            
            
            
      # the model for both the +validates_with+ and +validate+ methods.
           
        
      
        
          - 
            
            
            
            
      # It clears the validators that are created with an invocation of
           
        
      
        
          - 
            
            
            
            
      # +validates_with+ and the callbacks that are set by an invocation
           
        
      
        
          - 
            
            
            
            
      # of +validate+.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
      #     validates_with OtherValidator, on: :create
           
        
      
        
          - 
            
            
            
            
      #     validates_with StrictValidator, strict: true
           
        
      
        
          - 
            
            
            
            
      #     validate :cannot_be_robot
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def cannot_be_robot
           
        
      
        
          - 
            
            
            
            
      #       errors.add(:base, 'A person cannot be a robot') if person_is_robot
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.validators
           
        
      
        
          - 
            
            
            
            
      #   # => [
           
        
      
        
          - 
            
            
            
            
      #   #      #<MyValidator:0x007fbff403e808 @options={}>,
           
        
      
        
          - 
            
            
            
            
      #   #      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
           
        
      
        
          - 
            
            
            
            
      #   #      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
           
        
      
        
          - 
            
            
            
            
      #   #    ]
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If one runs <tt>Person.clear_validators!</tt> and then checks to see what
           
        
      
        
          - 
            
            
            
            
      # validators this class has, you would obtain:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.validators # => []
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Also, the callback set by <tt>validate :cannot_be_robot</tt> will be erased
           
        
      
        
          - 
            
            
            
            
      # so that:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person._validate_callbacks.empty?  # => true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            1
            
            
            
      def clear_validators!
           
        
      
        
          - 
            658
            
            
            
        reset_callbacks(:validate)
           
        
      
        
          - 
            658
            
            
            
        _validators.clear
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # List all validators that are being used to validate a specific attribute.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name , :age
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates_presence_of :name
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :age, in: 0..99
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Person.validators_on(:name)
           
        
      
        
          - 
            
            
            
            
      #   # => [
           
        
      
        
          - 
            
            
            
            
      #   #       #<ActiveModel::Validations::PresenceValidator:0x007fe604914e60 @attributes=[:name], @options={}>,
           
        
      
        
          - 
            
            
            
            
      #   #    ]
           
        
      
        
          - 
            1
            
            
            
      def validators_on(*attributes)
           
        
      
        
          - 
            7
            
            
            
        attributes.flat_map do |attribute|
           
        
      
        
          - 
            8
            
            
            
          _validators[attribute.to_sym]
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Returns +true+ if +attribute+ is an attribute method, +false+ otherwise.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #  class Person
           
        
      
        
          - 
            
            
            
            
      #    include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #    attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #  end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #  User.attribute_method?(:name) # => true
           
        
      
        
          - 
            
            
            
            
      #  User.attribute_method?(:age)  # => false
           
        
      
        
          - 
            1
            
            
            
      def attribute_method?(attribute)
           
        
      
        
          - 
            22
            
            
            
        method_defined?(attribute)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # Copy validators on inheritance.
           
        
      
        
          - 
            1
            
            
            
      def inherited(base) #:nodoc:
           
        
      
        
          - 
            158
            
            
            
        dup = _validators.dup
           
        
      
        
          - 
            158
            
            
            
        base._validators = dup.each { |k, v| dup[k] = v.dup }
           
        
      
        
          - 
            158
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Clean the +Errors+ object if instance is duped.
           
        
      
        
          - 
            1
            
            
            
    def initialize_dup(other) #:nodoc:
           
        
      
        
          - 
            2
            
            
            
      @errors = nil
           
        
      
        
          - 
            2
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the +Errors+ object that holds all information about attribute
           
        
      
        
          - 
            
            
            
            
    # error messages.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.valid? # => false
           
        
      
        
          - 
            
            
            
            
    #   person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
           
        
      
        
          - 
            1
            
            
            
    def errors
           
        
      
        
          - 
            3292
            
            
            
      @errors ||= Errors.new(self)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Runs all the specified validations and returns +true+ if no errors were
           
        
      
        
          - 
            
            
            
            
    # added otherwise +false+.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.name = ''
           
        
      
        
          - 
            
            
            
            
    #   person.valid? # => false
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'david'
           
        
      
        
          - 
            
            
            
            
    #   person.valid? # => true
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Context can optionally be supplied to define which callbacks to test
           
        
      
        
          - 
            
            
            
            
    # against (the context is defined on the validations using <tt>:on</tt>).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name, on: :new
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.valid?       # => true
           
        
      
        
          - 
            
            
            
            
    #   person.valid?(:new) # => false
           
        
      
        
          - 
            1
            
            
            
    def valid?(context = nil)
           
        
      
        
          - 
            918
            
            
            
      current_context, self.validation_context = validation_context, context
           
        
      
        
          - 
            918
            
            
            
      errors.clear
           
        
      
        
          - 
            918
            
            
            
      run_validations!
           
        
      
        
          - 
            
            
            
            
    ensure
           
        
      
        
          - 
            918
            
            
            
      self.validation_context = current_context
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    alias_method :validate, :valid?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Performs the opposite of <tt>valid?</tt>. Returns +true+ if errors were
           
        
      
        
          - 
            
            
            
            
    # added, +false+ otherwise.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.name = ''
           
        
      
        
          - 
            
            
            
            
    #   person.invalid? # => true
           
        
      
        
          - 
            
            
            
            
    #   person.name = 'david'
           
        
      
        
          - 
            
            
            
            
    #   person.invalid? # => false
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Context can optionally be supplied to define which callbacks to test
           
        
      
        
          - 
            
            
            
            
    # against (the context is defined on the validations using <tt>:on</tt>).
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
    #     validates_presence_of :name, on: :new
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   person = Person.new
           
        
      
        
          - 
            
            
            
            
    #   person.invalid?       # => false
           
        
      
        
          - 
            
            
            
            
    #   person.invalid?(:new) # => true
           
        
      
        
          - 
            1
            
            
            
    def invalid?(context = nil)
           
        
      
        
          - 
            358
            
            
            
      !valid?(context)
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Runs all the validations within the specified context. Returns +true+ if
           
        
      
        
          - 
            
            
            
            
    # no errors are found, raises +ValidationError+ otherwise.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Validations with no <tt>:on</tt> option will run no matter the context. Validations with
           
        
      
        
          - 
            
            
            
            
    # some <tt>:on</tt> option will only run in the specified context.
           
        
      
        
          - 
            1
            
            
            
    def validate!(context = nil)
           
        
      
        
          - 
            3
            
            
            
      valid?(context) || raise_validation_error
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Hook method defining how an attribute value should be retrieved. By default
           
        
      
        
          - 
            
            
            
            
    # this is assumed to be an instance named after the attribute. Override this
           
        
      
        
          - 
            
            
            
            
    # method in subclasses should you need to retrieve the value for a given
           
        
      
        
          - 
            
            
            
            
    # attribute differently:
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class MyClass
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def initialize(data = {})
           
        
      
        
          - 
            
            
            
            
    #       @data = data
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def read_attribute_for_validation(key)
           
        
      
        
          - 
            
            
            
            
    #       @data[key]
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            1
            
            
            
    alias :read_attribute_for_validation :send
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
  private
           
        
      
        
          - 
            1
            
            
            
    def run_validations!
           
        
      
        
          - 
            917
            
            
            
      _run_validate_callbacks
           
        
      
        
          - 
            910
            
            
            
      errors.empty?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def raise_validation_error # :doc:
           
        
      
        
          - 
            2
            
            
            
      raise(ValidationError.new(self))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # = Active Model ValidationError
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Raised by <tt>validate!</tt> when the model is invalid. Use the
           
        
      
        
          - 
            
            
            
            
  # +model+ method to retrieve the record which did not validate.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   begin
           
        
      
        
          - 
            
            
            
            
  #     complex_operation_that_internally_calls_validate!
           
        
      
        
          - 
            
            
            
            
  #   rescue ActiveModel::ValidationError => invalid
           
        
      
        
          - 
            
            
            
            
  #     puts invalid.model.errors
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            1
            
            
            
  class ValidationError < StandardError
           
        
      
        
          - 
            1
            
            
            
    attr_reader :model
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    def initialize(model)
           
        
      
        
          - 
            2
            
            
            
      @model = model
           
        
      
        
          - 
            2
            
            
            
      errors = @model.errors.full_messages.join(", ")
           
        
      
        
          - 
            2
            
            
            
      super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :"errors.messages.model_invalid"))
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            15
            
            
            
Dir[File.expand_path("validations/*.rb", __dir__)].each { |file| require file }
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            
            
            
            
    # == \Active \Model Absence Validator
           
        
      
        
          - 
            1
            
            
            
    class AbsenceValidator < EachValidator #:nodoc:
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attr_name, value)
           
        
      
        
          - 
            13
            
            
            
        record.errors.add(attr_name, :present, **options) if value.present?
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Validates that the specified attributes are blank (as defined by
           
        
      
        
          - 
            
            
            
            
      # Object#present?). Happens by default on save.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_absence_of :first_name
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The first_name attribute must be in the object and it must be blank.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "must be blank").
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_absence_of(*attr_names)
           
        
      
        
          - 
            5
            
            
            
        validates_with AbsenceValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class AcceptanceValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def initialize(options)
           
        
      
        
          - 
            22
            
            
            
        super({ allow_nil: true, accept: ["1", true] }.merge!(options))
           
        
      
        
          - 
            22
            
            
            
        setup!(options[:class])
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            20
            
            
            
        unless acceptable_option?(value)
           
        
      
        
          - 
            13
            
            
            
          record.errors.add(attribute, :accepted, **options.except(:accept, :allow_nil))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def setup!(klass)
           
        
      
        
          - 
            22
            
            
            
          define_attributes = LazilyDefineAttributes.new(attributes)
           
        
      
        
          - 
            22
            
            
            
          klass.include(define_attributes) unless klass.included_modules.include?(define_attributes)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def acceptable_option?(value)
           
        
      
        
          - 
            20
            
            
            
          Array(options[:accept]).include?(value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        class LazilyDefineAttributes < Module
           
        
      
        
          - 
            1
            
            
            
          def initialize(attributes)
           
        
      
        
          - 
            22
            
            
            
            @attributes = attributes.map(&:to_s)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def included(klass)
           
        
      
        
          - 
            20
            
            
            
            @lock = Mutex.new
           
        
      
        
          - 
            20
            
            
            
            mod = self
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            20
            
            
            
            define_method(:respond_to_missing?) do |method_name, include_private = false|
           
        
      
        
          - 
            4
            
            
            
              mod.define_on(klass)
           
        
      
        
          - 
            4
            
            
            
              super(method_name, include_private) || mod.matches?(method_name)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            20
            
            
            
            define_method(:method_missing) do |method_name, *args, &block|
           
        
      
        
          - 
            7
            
            
            
              mod.define_on(klass)
           
        
      
        
          - 
            7
            
            
            
              if mod.matches?(method_name)
           
        
      
        
          - 
            7
            
            
            
                send(method_name, *args, &block)
           
        
      
        
          - 
            
            
            
            
              else
           
        
      
        
          - 
            
            
            
            
                super(method_name, *args, &block)
           
        
      
        
          - 
            
            
            
            
              end
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def matches?(method_name)
           
        
      
        
          - 
            11
            
            
            
            attr_name = method_name.to_s.chomp("=")
           
        
      
        
          - 
            22
            
            
            
            attributes.any? { |name| name == attr_name }
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def define_on(klass)
           
        
      
        
          - 
            11
            
            
            
            @lock&.synchronize do
           
        
      
        
          - 
            11
            
            
            
              return unless @lock
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            22
            
            
            
              attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
           
        
      
        
          - 
            22
            
            
            
              attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            11
            
            
            
              attr_reader(*attr_readers)
           
        
      
        
          - 
            11
            
            
            
              attr_writer(*attr_writers)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            11
            
            
            
              remove_method :respond_to_missing?
           
        
      
        
          - 
            11
            
            
            
              remove_method :method_missing
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            11
            
            
            
              @lock = nil
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          def ==(other)
           
        
      
        
          - 
            4
            
            
            
            self.class == other.class && attributes == other.attributes
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
          protected
           
        
      
        
          - 
            1
            
            
            
            attr_reader :attributes
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Encapsulates the pattern of wanting to validate the acceptance of a
           
        
      
        
          - 
            
            
            
            
      # terms of service check box (or similar agreement).
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_acceptance_of :terms_of_service
           
        
      
        
          - 
            
            
            
            
      #     validates_acceptance_of :eula, message: 'must be abided'
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If the database column does not exist, the +terms_of_service+ attribute
           
        
      
        
          - 
            
            
            
            
      # is entirely virtual. This check is performed only if +terms_of_service+
           
        
      
        
          - 
            
            
            
            
      # is not +nil+ and by default on save.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "must be
           
        
      
        
          - 
            
            
            
            
      #   accepted").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:accept</tt> - Specifies a value that is considered accepted.
           
        
      
        
          - 
            
            
            
            
      #   Also accepts an array of possible values. The default value is
           
        
      
        
          - 
            
            
            
            
      #   an array ["1", true], which makes it easy to relate to an HTML
           
        
      
        
          - 
            
            
            
            
      #   checkbox. This should be set to, or include, +true+ if you are validating
           
        
      
        
          - 
            
            
            
            
      #   a database column, since the attribute is typecast from "1" to +true+
           
        
      
        
          - 
            
            
            
            
      #   before validation.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information.
           
        
      
        
          - 
            1
            
            
            
      def validates_acceptance_of(*attr_names)
           
        
      
        
          - 
            22
            
            
            
        validates_with AcceptanceValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            
            
            
            
    # == Active \Model \Validation \Callbacks
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Provides an interface for any class to have +before_validation+ and
           
        
      
        
          - 
            
            
            
            
    # +after_validation+ callbacks.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # First, include ActiveModel::Validations::Callbacks from the class you are
           
        
      
        
          - 
            
            
            
            
    # creating:
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class MyModel
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations::Callbacks
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     before_validation :do_stuff_before_validation
           
        
      
        
          - 
            
            
            
            
    #     after_validation  :do_stuff_after_validation
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Like other <tt>before_*</tt> callbacks if +before_validation+ throws
           
        
      
        
          - 
            
            
            
            
    # +:abort+ then <tt>valid?</tt> will not be called.
           
        
      
        
          - 
            1
            
            
            
    module Callbacks
           
        
      
        
          - 
            1
            
            
            
      extend ActiveSupport::Concern
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      included do
           
        
      
        
          - 
            2
            
            
            
        include ActiveSupport::Callbacks
           
        
      
        
          - 
            2
            
            
            
        define_callbacks :validation,
           
        
      
        
          - 
            
            
            
            
                         skip_after_callbacks_if_terminated: true,
           
        
      
        
          - 
            
            
            
            
                         scope: [:kind, :name]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      module ClassMethods
           
        
      
        
          - 
            
            
            
            
        # Defines a callback that will get called right before validation.
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   class Person
           
        
      
        
          - 
            
            
            
            
        #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
        #     include ActiveModel::Validations::Callbacks
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     validates_length_of :name, maximum: 6
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     before_validation :remove_whitespaces
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     private
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     def remove_whitespaces
           
        
      
        
          - 
            
            
            
            
        #       name.strip!
           
        
      
        
          - 
            
            
            
            
        #     end
           
        
      
        
          - 
            
            
            
            
        #   end
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   person = Person.new
           
        
      
        
          - 
            
            
            
            
        #   person.name = '  bob  '
           
        
      
        
          - 
            
            
            
            
        #   person.valid? # => true
           
        
      
        
          - 
            
            
            
            
        #   person.name   # => "bob"
           
        
      
        
          - 
            1
            
            
            
        def before_validation(*args, &block)
           
        
      
        
          - 
            14
            
            
            
          options = args.extract_options!
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            14
            
            
            
          if options.key?(:on)
           
        
      
        
          - 
            3
            
            
            
            options = options.dup
           
        
      
        
          - 
            3
            
            
            
            options[:on] = Array(options[:on])
           
        
      
        
          - 
            3
            
            
            
            options[:if] = Array(options[:if])
           
        
      
        
          - 
            3
            
            
            
            options[:if].unshift ->(o) {
           
        
      
        
          - 
            13
            
            
            
              !(options[:on] & Array(o.validation_context)).empty?
           
        
      
        
          - 
            
            
            
            
            }
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            14
            
            
            
          set_callback(:validation, :before, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
        # Defines a callback that will get called right after validation.
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   class Person
           
        
      
        
          - 
            
            
            
            
        #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
        #     include ActiveModel::Validations::Callbacks
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     attr_accessor :name, :status
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     validates_presence_of :name
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     after_validation :set_status
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     private
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #     def set_status
           
        
      
        
          - 
            
            
            
            
        #       self.status = errors.empty?
           
        
      
        
          - 
            
            
            
            
        #     end
           
        
      
        
          - 
            
            
            
            
        #   end
           
        
      
        
          - 
            
            
            
            
        #
           
        
      
        
          - 
            
            
            
            
        #   person = Person.new
           
        
      
        
          - 
            
            
            
            
        #   person.name = ''
           
        
      
        
          - 
            
            
            
            
        #   person.valid? # => false
           
        
      
        
          - 
            
            
            
            
        #   person.status # => false
           
        
      
        
          - 
            
            
            
            
        #   person.name = 'bob'
           
        
      
        
          - 
            
            
            
            
        #   person.valid? # => true
           
        
      
        
          - 
            
            
            
            
        #   person.status # => true
           
        
      
        
          - 
            1
            
            
            
        def after_validation(*args, &block)
           
        
      
        
          - 
            10
            
            
            
          options = args.extract_options!
           
        
      
        
          - 
            10
            
            
            
          options = options.dup
           
        
      
        
          - 
            10
            
            
            
          options[:prepend] = true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            10
            
            
            
          if options.key?(:on)
           
        
      
        
          - 
            3
            
            
            
            options[:on] = Array(options[:on])
           
        
      
        
          - 
            3
            
            
            
            options[:if] = Array(options[:if])
           
        
      
        
          - 
            3
            
            
            
            options[:if].unshift ->(o) {
           
        
      
        
          - 
            13
            
            
            
              !(options[:on] & Array(o.validation_context)).empty?
           
        
      
        
          - 
            
            
            
            
            }
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            10
            
            
            
          set_callback(:validation, :after, *args, options, &block)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            
            
            
            
      # Overwrite run validations to include callbacks.
           
        
      
        
          - 
            1
            
            
            
      def run_validations!
           
        
      
        
          - 
            1447
            
            
            
        _run_validation_callbacks { super }
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/range"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    module Clusivity #:nodoc:
           
        
      
        
          - 
            1
            
            
            
      ERROR_MESSAGE = "An object with the method #include? or a proc, lambda or symbol is required, " \
           
        
      
        
          - 
            
            
            
            
                      "and must be supplied as the :in (or :within) option of the configuration hash"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def check_validity!
           
        
      
        
          - 
            52
            
            
            
        unless delimiter.respond_to?(:include?) || delimiter.respond_to?(:call) || delimiter.respond_to?(:to_sym)
           
        
      
        
          - 
            2
            
            
            
          raise ArgumentError, ERROR_MESSAGE
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def include?(record, value)
           
        
      
        
          - 
            86
            
            
            
        members = if delimiter.respond_to?(:call)
           
        
      
        
          - 
            4
            
            
            
          delimiter.call(record)
           
        
      
        
          - 
            82
            
            
            
        elsif delimiter.respond_to?(:to_sym)
           
        
      
        
          - 
            4
            
            
            
          record.send(delimiter)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            78
            
            
            
          delimiter
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            86
            
            
            
        if value.is_a?(Array)
           
        
      
        
          - 
            5
            
            
            
          value.all? { |v| members.send(inclusion_method(members), v) }
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            84
            
            
            
          members.send(inclusion_method(members), value)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def delimiter
           
        
      
        
          - 
            316
            
            
            
        @delimiter ||= options[:in] || options[:within]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # After Ruby 2.2, <tt>Range#include?</tt> on non-number-or-time-ish ranges checks all
           
        
      
        
          - 
            
            
            
            
      # possible values in the range for equality, which is slower but more accurate.
           
        
      
        
          - 
            
            
            
            
      # <tt>Range#cover?</tt> uses the previous logic of comparing a value with the range
           
        
      
        
          - 
            
            
            
            
      # endpoints, which is fast but is only accurate on Numeric, Time, Date,
           
        
      
        
          - 
            
            
            
            
      # or DateTime ranges.
           
        
      
        
          - 
            1
            
            
            
      def inclusion_method(enumerable)
           
        
      
        
          - 
            87
            
            
            
        if enumerable.is_a? Range
           
        
      
        
          - 
            29
            
            
            
          case enumerable.first
           
        
      
        
          - 
            
            
            
            
          when Numeric, Time, DateTime, Date
           
        
      
        
          - 
            21
            
            
            
            :cover?
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            8
            
            
            
            :include?
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            58
            
            
            
          :include?
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class ConfirmationValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def initialize(options)
           
        
      
        
          - 
            19
            
            
            
        super({ case_sensitive: true }.merge!(options))
           
        
      
        
          - 
            19
            
            
            
        setup!(options[:class])
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            35
            
            
            
        unless (confirmed = record.send("#{attribute}_confirmation")).nil?
           
        
      
        
          - 
            30
            
            
            
          unless confirmation_value_equal?(record, attribute, value, confirmed)
           
        
      
        
          - 
            19
            
            
            
            human_attribute_name = record.class.human_attribute_name(attribute)
           
        
      
        
          - 
            19
            
            
            
            record.errors.add(:"#{attribute}_confirmation", :confirmation, **options.except(:case_sensitive).merge!(attribute: human_attribute_name))
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def setup!(klass)
           
        
      
        
          - 
            19
            
            
            
          klass.attr_reader(*attributes.map do |attribute|
           
        
      
        
          - 
            19
            
            
            
            :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation")
           
        
      
        
          - 
            
            
            
            
          end.compact)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            19
            
            
            
          klass.attr_writer(*attributes.map do |attribute|
           
        
      
        
          - 
            19
            
            
            
            :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=")
           
        
      
        
          - 
            
            
            
            
          end.compact)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def confirmation_value_equal?(record, attribute, value, confirmed)
           
        
      
        
          - 
            30
            
            
            
          if !options[:case_sensitive] && value.is_a?(String)
           
        
      
        
          - 
            1
            
            
            
            value.casecmp(confirmed) == 0
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            29
            
            
            
            value == confirmed
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Encapsulates the pattern of wanting to validate a password or email
           
        
      
        
          - 
            
            
            
            
      # address field with a confirmation.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   Model:
           
        
      
        
          - 
            
            
            
            
      #     class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #       validates_confirmation_of :user_name, :password
           
        
      
        
          - 
            
            
            
            
      #       validates_confirmation_of :email_address,
           
        
      
        
          - 
            
            
            
            
      #                                 message: 'should match confirmation'
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   View:
           
        
      
        
          - 
            
            
            
            
      #     <%= password_field "person", "password" %>
           
        
      
        
          - 
            
            
            
            
      #     <%= password_field "person", "password_confirmation" %>
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The added +password_confirmation+ attribute is virtual; it exists only
           
        
      
        
          - 
            
            
            
            
      # as an in-memory attribute for validating the password. To achieve this,
           
        
      
        
          - 
            
            
            
            
      # the validation adds accessors to the model for the confirmation
           
        
      
        
          - 
            
            
            
            
      # attribute.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # NOTE: This check is performed only if +password_confirmation+ is not
           
        
      
        
          - 
            
            
            
            
      # +nil+. To require confirmation, make sure to add a presence check for
           
        
      
        
          - 
            
            
            
            
      # the confirmation attribute:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates_presence_of :password_confirmation, if: :password_changed?
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "doesn't match
           
        
      
        
          - 
            
            
            
            
      #   <tt>%{translated_attribute_name}</tt>").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by
           
        
      
        
          - 
            
            
            
            
      #   non-text columns (+true+ by default).
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_confirmation_of(*attr_names)
           
        
      
        
          - 
            18
            
            
            
        validates_with ConfirmationValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/validations/clusivity"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class ExclusionValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Clusivity
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            29
            
            
            
        if include?(record, value)
           
        
      
        
          - 
            22
            
            
            
          record.errors.add(attribute, :exclusion, **options.except(:in, :within).merge!(value: value))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Validates that the value of the specified attribute is not in a
           
        
      
        
          - 
            
            
            
            
      # particular enumerable object.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_exclusion_of :username, in: %w( admin superuser ), message: "You don't belong here"
           
        
      
        
          - 
            
            
            
            
      #     validates_exclusion_of :age, in: 30..60, message: 'This site is only for under 30 and over 60'
           
        
      
        
          - 
            
            
            
            
      #     validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed"
           
        
      
        
          - 
            
            
            
            
      #     validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] },
           
        
      
        
          - 
            
            
            
            
      #                            message: 'should not be the same as your username or first name'
           
        
      
        
          - 
            
            
            
            
      #     validates_exclusion_of :karma, in: :reserved_karmas
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:in</tt> - An enumerable object of items that the value shouldn't
           
        
      
        
          - 
            
            
            
            
      #   be part of. This can be supplied as a proc, lambda or symbol which returns an
           
        
      
        
          - 
            
            
            
            
      #   enumerable. If the enumerable is a numerical, time or datetime range the test
           
        
      
        
          - 
            
            
            
            
      #   is performed with <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>. When
           
        
      
        
          - 
            
            
            
            
      #   using a proc or lambda the instance under validation is passed as an argument.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
           
        
      
        
          - 
            
            
            
            
      #   <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - Specifies a custom error message (default is: "is
           
        
      
        
          - 
            
            
            
            
      #   reserved").
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_exclusion_of(*attr_names)
           
        
      
        
          - 
            21
            
            
            
        validates_with ExclusionValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class FormatValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            37
            
            
            
        if options[:with]
           
        
      
        
          - 
            33
            
            
            
          regexp = option_call(record, :with)
           
        
      
        
          - 
            33
            
            
            
          record_error(record, attribute, :with, value) unless regexp.match?(value.to_s)
           
        
      
        
          - 
            4
            
            
            
        elsif options[:without]
           
        
      
        
          - 
            4
            
            
            
          regexp = option_call(record, :without)
           
        
      
        
          - 
            4
            
            
            
          record_error(record, attribute, :without, value) if regexp.match?(value.to_s)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def check_validity!
           
        
      
        
          - 
            25
            
            
            
        unless options.include?(:with) ^ options.include?(:without)  # ^ == xor, or "exclusive or"
           
        
      
        
          - 
            3
            
            
            
          raise ArgumentError, "Either :with or :without must be supplied (but not both)"
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            22
            
            
            
        check_options_validity :with
           
        
      
        
          - 
            20
            
            
            
        check_options_validity :without
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def option_call(record, name)
           
        
      
        
          - 
            37
            
            
            
          option = options[name]
           
        
      
        
          - 
            37
            
            
            
          option.respond_to?(:call) ? option.call(record) : option
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def record_error(record, attribute, name, value)
           
        
      
        
          - 
            21
            
            
            
          record.errors.add(attribute, :invalid, **options.except(name).merge!(value: value))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def check_options_validity(name)
           
        
      
        
          - 
            42
            
            
            
          if option = options[name]
           
        
      
        
          - 
            22
            
            
            
            if option.is_a?(Regexp)
           
        
      
        
          - 
            18
            
            
            
              if options[:multiline] != true && regexp_using_multiline_anchors?(option)
           
        
      
        
          - 
            1
            
            
            
                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
           
        
      
        
          - 
            4
            
            
            
            elsif !option.respond_to?(:call)
           
        
      
        
          - 
            2
            
            
            
              raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}"
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
        def regexp_using_multiline_anchors?(regexp)
           
        
      
        
          - 
            17
            
            
            
          source = regexp.source
           
        
      
        
          - 
            17
            
            
            
          source.start_with?("^") || (source.end_with?("$") && !source.end_with?("\\$"))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Validates whether the value of the specified attribute is of the correct
           
        
      
        
          - 
            
            
            
            
      # form, going by the regular expression provided. You can require that the
           
        
      
        
          - 
            
            
            
            
      # attribute matches the regular expression:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Alternatively, you can require that the specified attribute does _not_
           
        
      
        
          - 
            
            
            
            
      # match the regular expression:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_format_of :email, without: /NOSPAM/
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # You can also provide a proc or lambda which will determine the regular
           
        
      
        
          - 
            
            
            
            
      # expression that will be used to validate the attribute.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     # Admin can have number as a first letter in their screen name
           
        
      
        
          - 
            
            
            
            
      #     validates_format_of :screen_name,
           
        
      
        
          - 
            
            
            
            
      #                         with: ->(person) { person.admin? ? /\A[a-z0-9][a-z0-9_\-]*\z/i : /\A[a-z][a-z0-9_\-]*\z/i }
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Note: use <tt>\A</tt> and <tt>\z</tt> to match the start and end of the
           
        
      
        
          - 
            
            
            
            
      # string, <tt>^</tt> and <tt>$</tt> match the start/end of a line.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Due to frequent misuse of <tt>^</tt> and <tt>$</tt>, you need to pass
           
        
      
        
          - 
            
            
            
            
      # the <tt>multiline: true</tt> option in case you use any of these two
           
        
      
        
          - 
            
            
            
            
      # anchors in the provided regular expression. In most cases, you should be
           
        
      
        
          - 
            
            
            
            
      # using <tt>\A</tt> and <tt>\z</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # You must pass either <tt>:with</tt> or <tt>:without</tt> as an option.
           
        
      
        
          - 
            
            
            
            
      # In addition, both must be a regular expression or a proc or lambda, or
           
        
      
        
          - 
            
            
            
            
      # else an exception will be raised.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "is invalid").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:with</tt> - Regular expression that if the attribute matches will
           
        
      
        
          - 
            
            
            
            
      #   result in a successful validation. This can be provided as a proc or
           
        
      
        
          - 
            
            
            
            
      #   lambda returning regular expression which will be called at runtime.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:without</tt> - Regular expression that if the attribute does not
           
        
      
        
          - 
            
            
            
            
      #   match will result in a successful validation. This can be provided as
           
        
      
        
          - 
            
            
            
            
      #   a proc or lambda returning regular expression which will be called at
           
        
      
        
          - 
            
            
            
            
      #   runtime.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:multiline</tt> - Set to true if your regular expression contains
           
        
      
        
          - 
            
            
            
            
      #   anchors that match the beginning or end of lines as opposed to the
           
        
      
        
          - 
            
            
            
            
      #   beginning or end of the string. These anchors are <tt>^</tt> and <tt>$</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_format_of(*attr_names)
           
        
      
        
          - 
            23
            
            
            
        validates_with FormatValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def _merge_attributes(attr_names)
           
        
      
        
          - 
            323
            
            
            
          options = attr_names.extract_options!.symbolize_keys
           
        
      
        
          - 
            323
            
            
            
          attr_names.flatten!
           
        
      
        
          - 
            323
            
            
            
          options[:attributes] = attr_names
           
        
      
        
          - 
            323
            
            
            
          options
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_model/validations/clusivity"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class InclusionValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      include Clusivity
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            57
            
            
            
        unless include?(record, value)
           
        
      
        
          - 
            35
            
            
            
          record.errors.add(attribute, :inclusion, **options.except(:in, :within).merge!(value: value))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Validates whether the value of the specified attribute is available in a
           
        
      
        
          - 
            
            
            
            
      # particular enumerable object.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :role, in: %w( admin contributor )
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :age, in: 0..99
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :states, in: ->(person) { STATES[person.country] }
           
        
      
        
          - 
            
            
            
            
      #     validates_inclusion_of :karma, in: :available_karmas
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:in</tt> - An enumerable object of available items. This can be
           
        
      
        
          - 
            
            
            
            
      #   supplied as a proc, lambda or symbol which returns an enumerable. If the
           
        
      
        
          - 
            
            
            
            
      #   enumerable is a numerical, time or datetime range the test is performed
           
        
      
        
          - 
            
            
            
            
      #   with <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>. When using
           
        
      
        
          - 
            
            
            
            
      #   a proc or lambda the instance under validation is passed as an argument.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - Specifies a custom error message (default is: "is
           
        
      
        
          - 
            
            
            
            
      #   not included in the list").
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_inclusion_of(*attr_names)
           
        
      
        
          - 
            30
            
            
            
        validates_with InclusionValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class LengthValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      MESSAGES  = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze
           
        
      
        
          - 
            1
            
            
            
      CHECKS    = { is: :==, minimum: :>=, maximum: :<= }.freeze
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :too_short, :too_long]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def initialize(options)
           
        
      
        
          - 
            100
            
            
            
        if range = (options.delete(:in) || options.delete(:within))
           
        
      
        
          - 
            29
            
            
            
          raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
           
        
      
        
          - 
            27
            
            
            
          options[:minimum], options[:maximum] = range.min, range.max
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
        if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil?
           
        
      
        
          - 
            1
            
            
            
          options[:minimum] = 1
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
        super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def check_validity!
           
        
      
        
          - 
            98
            
            
            
        keys = CHECKS.keys & options.keys
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
        if keys.empty?
           
        
      
        
          - 
            
            
            
            
          raise ArgumentError, "Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option."
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            98
            
            
            
        keys.each do |key|
           
        
      
        
          - 
            128
            
            
            
          value = options[key]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            128
            
            
            
          unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc)
           
        
      
        
          - 
            4
            
            
            
            raise ArgumentError, ":#{key} must be a non-negative Integer, Infinity, Symbol, or Proc"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            143
            
            
            
        value_length = value.respond_to?(:length) ? value.length : value.to_s.length
           
        
      
        
          - 
            143
            
            
            
        errors_options = options.except(*RESERVED_OPTIONS)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            143
            
            
            
        CHECKS.each do |key, validity_check|
           
        
      
        
          - 
            429
            
            
            
          next unless check_value = options[key]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            191
            
            
            
          if !value.nil? || skip_nil_check?(key)
           
        
      
        
          - 
            160
            
            
            
            case check_value
           
        
      
        
          - 
            
            
            
            
            when Proc
           
        
      
        
          - 
            6
            
            
            
              check_value = check_value.call(record)
           
        
      
        
          - 
            
            
            
            
            when Symbol
           
        
      
        
          - 
            
            
            
            
              check_value = record.send(check_value)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            160
            
            
            
            next if value_length.send(validity_check, check_value)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            84
            
            
            
          errors_options[:count] = check_value
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            84
            
            
            
          default_message = options[MESSAGES[key]]
           
        
      
        
          - 
            84
            
            
            
          errors_options[:message] ||= default_message if default_message
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            84
            
            
            
          record.errors.add(attribute, MESSAGES[key], **errors_options)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      private
           
        
      
        
          - 
            1
            
            
            
        def skip_nil_check?(key)
           
        
      
        
          - 
            54
            
            
            
          key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil?
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    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:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :first_name, maximum: 30
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind"
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :fax, in: 7..32, allow_nil: true
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :phone, in: 7..32, allow_blank: true
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name'
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters'
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me."
           
        
      
        
          - 
            
            
            
            
      #     validates_length_of :words_in_essay, minimum: 100, too_short: 'Your essay must be at least 100 words.'
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     def words_in_essay
           
        
      
        
          - 
            
            
            
            
      #       essay.scan(/\w+/)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Constraint options:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # * <tt>:minimum</tt> - The minimum size of the attribute.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:maximum</tt> - The maximum size of the attribute. Allows +nil+ by
           
        
      
        
          - 
            
            
            
            
      #   default if not used with +:minimum+.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:is</tt> - The exact size of the attribute.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:within</tt> - A range specifying the minimum and maximum size of
           
        
      
        
          - 
            
            
            
            
      #   the attribute.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:in</tt> - A synonym (or alias) for <tt>:within</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Other options:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:too_long</tt> - The error message if the attribute goes over the
           
        
      
        
          - 
            
            
            
            
      #   maximum (default is: "is too long (maximum is %{count} characters)").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:too_short</tt> - The error message if the attribute goes under the
           
        
      
        
          - 
            
            
            
            
      #   minimum (default is: "is too short (minimum is %{count} characters)").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt>
           
        
      
        
          - 
            
            
            
            
      #   method and the attribute is the wrong size (default is: "is the wrong
           
        
      
        
          - 
            
            
            
            
      #   length (should be %{count} characters)").
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>,
           
        
      
        
          - 
            
            
            
            
      #   <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate
           
        
      
        
          - 
            
            
            
            
      #   <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+ and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_length_of(*attr_names)
           
        
      
        
          - 
            95
            
            
            
        validates_with LengthValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      alias_method :validates_size_of, :validates_length_of
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "bigdecimal/util"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class NumericalityValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
           
        
      
        
          - 
            
            
            
            
                 equal_to: :==, less_than: :<, less_than_or_equal_to: :<=,
           
        
      
        
          - 
            
            
            
            
                 odd: :odd?, even: :even?, other_than: :!= }.freeze
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      INTEGER_REGEX = /\A[+-]?\d+\z/
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      HEXADECIMAL_REGEX = /\A[+-]?0[xX]/
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def check_validity!
           
        
      
        
          - 
            76
            
            
            
        keys = CHECKS.keys - [:odd, :even]
           
        
      
        
          - 
            76
            
            
            
        options.slice(*keys).each do |option, value|
           
        
      
        
          - 
            38
            
            
            
          unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
           
        
      
        
          - 
            5
            
            
            
            raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attr_name, value, precision: Float::DIG, scale: nil)
           
        
      
        
          - 
            482
            
            
            
        unless is_number?(value, precision, scale)
           
        
      
        
          - 
            132
            
            
            
          record.errors.add(attr_name, :not_a_number, **filtered_options(value))
           
        
      
        
          - 
            132
            
            
            
          return
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            350
            
            
            
        if allow_only_integer?(record) && !is_integer?(value)
           
        
      
        
          - 
            46
            
            
            
          record.errors.add(attr_name, :not_an_integer, **filtered_options(value))
           
        
      
        
          - 
            46
            
            
            
          return
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            304
            
            
            
        value = parse_as_number(value, precision, scale)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            304
            
            
            
        options.slice(*CHECKS.keys).each do |option, option_value|
           
        
      
        
          - 
            136
            
            
            
          case option
           
        
      
        
          - 
            
            
            
            
          when :odd, :even
           
        
      
        
          - 
            20
            
            
            
            unless value.to_i.send(CHECKS[option])
           
        
      
        
          - 
            14
            
            
            
              record.errors.add(attr_name, option, **filtered_options(value))
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            116
            
            
            
            case option_value
           
        
      
        
          - 
            
            
            
            
            when Proc
           
        
      
        
          - 
            4
            
            
            
              option_value = option_value.call(record)
           
        
      
        
          - 
            
            
            
            
            when Symbol
           
        
      
        
          - 
            3
            
            
            
              option_value = record.send(option_value)
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            116
            
            
            
            option_value = parse_as_number(option_value, precision, scale)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            116
            
            
            
            unless value.send(CHECKS[option], option_value)
           
        
      
        
          - 
            61
            
            
            
              record.errors.add(attr_name, option, **filtered_options(value).merge!(count: option_value))
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def parse_as_number(raw_value, precision, scale)
           
        
      
        
          - 
            902
            
            
            
        if raw_value.is_a?(Float)
           
        
      
        
          - 
            102
            
            
            
          parse_float(raw_value, precision, scale)
           
        
      
        
          - 
            800
            
            
            
        elsif raw_value.is_a?(Numeric)
           
        
      
        
          - 
            328
            
            
            
          raw_value
           
        
      
        
          - 
            472
            
            
            
        elsif is_integer?(raw_value)
           
        
      
        
          - 
            162
            
            
            
          raw_value.to_i
           
        
      
        
          - 
            310
            
            
            
        elsif !is_hexadecimal_literal?(raw_value)
           
        
      
        
          - 
            275
            
            
            
          parse_float(Kernel.Float(raw_value), precision, scale)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def parse_float(raw_value, precision, scale)
           
        
      
        
          - 
            280
            
            
            
        (scale ? raw_value.truncate(scale) : raw_value).to_d(precision)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def is_number?(raw_value, precision, scale)
           
        
      
        
          - 
            482
            
            
            
        !parse_as_number(raw_value, precision, scale).nil?
           
        
      
        
          - 
            
            
            
            
      rescue ArgumentError, TypeError
           
        
      
        
          - 
            97
            
            
            
        false
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def is_integer?(raw_value)
           
        
      
        
          - 
            556
            
            
            
        INTEGER_REGEX.match?(raw_value.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def is_hexadecimal_literal?(raw_value)
           
        
      
        
          - 
            310
            
            
            
        HEXADECIMAL_REGEX.match?(raw_value.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def filtered_options(value)
           
        
      
        
          - 
            253
            
            
            
        filtered = options.except(*RESERVED_OPTIONS)
           
        
      
        
          - 
            253
            
            
            
        filtered[:value] = value
           
        
      
        
          - 
            253
            
            
            
        filtered
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def allow_only_integer?(record)
           
        
      
        
          - 
            350
            
            
            
        case options[:only_integer]
           
        
      
        
          - 
            
            
            
            
        when Symbol
           
        
      
        
          - 
            30
            
            
            
          record.send(options[:only_integer])
           
        
      
        
          - 
            
            
            
            
        when Proc
           
        
      
        
          - 
            30
            
            
            
          options[:only_integer].call(record)
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            290
            
            
            
          options[:only_integer]
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def read_attribute_for_validation(record, attr_name)
           
        
      
        
          - 
            488
            
            
            
        return super if record_attribute_changed_in_place?(record, attr_name)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            488
            
            
            
        came_from_user = :"#{attr_name}_came_from_user?"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            488
            
            
            
        if record.respond_to?(came_from_user)
           
        
      
        
          - 
            
            
            
            
          if record.public_send(came_from_user)
           
        
      
        
          - 
            
            
            
            
            raw_value = record.read_attribute_before_type_cast(attr_name)
           
        
      
        
          - 
            
            
            
            
          elsif record.respond_to?(:read_attribute)
           
        
      
        
          - 
            
            
            
            
            raw_value = record.read_attribute(attr_name)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            488
            
            
            
          before_type_cast = :"#{attr_name}_before_type_cast"
           
        
      
        
          - 
            488
            
            
            
          if record.respond_to?(before_type_cast)
           
        
      
        
          - 
            2
            
            
            
            raw_value = record.public_send(before_type_cast)
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            488
            
            
            
        raw_value || super
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def record_attribute_changed_in_place?(record, attr_name)
           
        
      
        
          - 
            488
            
            
            
        record.respond_to?(:attribute_changed_in_place?) &&
           
        
      
        
          - 
            
            
            
            
          record.attribute_changed_in_place?(attr_name.to_s)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    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>
           
        
      
        
          - 
            
            
            
            
      # (if <tt>only_integer</tt> is set to +true+). Precision of Kernel.Float values
           
        
      
        
          - 
            
            
            
            
      # are guaranteed up to 15 digits.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_numericality_of :value, on: :create
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "is not a number").
           
        
      
        
          - 
            
            
            
            
      # * <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 Integer and Float columns empty strings are
           
        
      
        
          - 
            
            
            
            
      #   converted to +nil+.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:greater_than</tt> - Specifies the value must be greater than the
           
        
      
        
          - 
            
            
            
            
      #   supplied value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:greater_than_or_equal_to</tt> - Specifies the value must be
           
        
      
        
          - 
            
            
            
            
      #   greater than or equal the supplied value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied
           
        
      
        
          - 
            
            
            
            
      #   value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:less_than</tt> - Specifies the value must be less than the
           
        
      
        
          - 
            
            
            
            
      #   supplied value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less
           
        
      
        
          - 
            
            
            
            
      #   than or equal the supplied value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:other_than</tt> - Specifies the value must be other than the
           
        
      
        
          - 
            
            
            
            
      #   supplied value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:odd</tt> - Specifies the value must be an odd number.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:even</tt> - Specifies the value must be an even number.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+ .
           
        
      
        
          - 
            
            
            
            
      # 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:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # * <tt>:greater_than</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:greater_than_or_equal_to</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:equal_to</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:less_than</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:less_than_or_equal_to</tt>
           
        
      
        
          - 
            
            
            
            
      # * <tt>:only_integer</tt>
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # For example:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_numericality_of :width, less_than: ->(person) { person.height }
           
        
      
        
          - 
            
            
            
            
      #     validates_numericality_of :width, greater_than: :minimum_weight
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            1
            
            
            
      def validates_numericality_of(*attr_names)
           
        
      
        
          - 
            73
            
            
            
        validates_with NumericalityValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class PresenceValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attr_name, value)
           
        
      
        
          - 
            65
            
            
            
        record.errors.add(attr_name, :blank, **options) if value.blank?
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module HelperMethods
           
        
      
        
          - 
            
            
            
            
      # Validates that the specified attributes are not blank (as defined by
           
        
      
        
          - 
            
            
            
            
      # Object#blank?). Happens by default on save.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person < ActiveRecord::Base
           
        
      
        
          - 
            
            
            
            
      #     validates_presence_of :first_name
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The first_name attribute must be in the object and it cannot be blank.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If you want to validate the presence of a boolean field (where the real
           
        
      
        
          - 
            
            
            
            
      # values are +true+ and +false+), you will want to use
           
        
      
        
          - 
            
            
            
            
      # <tt>validates_inclusion_of :field_name, in: [true, false]</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # This is due to the way Object#blank? handles boolean values:
           
        
      
        
          - 
            
            
            
            
      # <tt>false.blank? # => true</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Configuration options:
           
        
      
        
          - 
            
            
            
            
      # * <tt>:message</tt> - A custom error message (default is: "can't be blank").
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # There is also a list of default options supported by every validator:
           
        
      
        
          - 
            
            
            
            
      # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+.
           
        
      
        
          - 
            
            
            
            
      # See <tt>ActiveModel::Validations#validates</tt> for more information
           
        
      
        
          - 
            1
            
            
            
      def validates_presence_of(*attr_names)
           
        
      
        
          - 
            34
            
            
            
        validates_with PresenceValidator, _merge_attributes(attr_names)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/hash/slice"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            
            
            
            
      # This method is a shortcut to all default validators and any custom
           
        
      
        
          - 
            
            
            
            
      # validator classes ending in 'Validator'. Note that Rails default
           
        
      
        
          - 
            
            
            
            
      # validators can be overridden inside specific classes by creating
           
        
      
        
          - 
            
            
            
            
      # custom validator classes in their place such as PresenceValidator.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Examples of using the default rails validators:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates :username, absence: true
           
        
      
        
          - 
            
            
            
            
      #   validates :terms, acceptance: true
           
        
      
        
          - 
            
            
            
            
      #   validates :password, confirmation: true
           
        
      
        
          - 
            
            
            
            
      #   validates :username, exclusion: { in: %w(admin superuser) }
           
        
      
        
          - 
            
            
            
            
      #   validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
           
        
      
        
          - 
            
            
            
            
      #   validates :age, inclusion: { in: 0..9 }
           
        
      
        
          - 
            
            
            
            
      #   validates :first_name, length: { maximum: 30 }
           
        
      
        
          - 
            
            
            
            
      #   validates :age, numericality: true
           
        
      
        
          - 
            
            
            
            
      #   validates :username, presence: true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The power of the +validates+ method comes when using custom validators
           
        
      
        
          - 
            
            
            
            
      # and default validators in one call for a given attribute.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class EmailValidator < ActiveModel::EachValidator
           
        
      
        
          - 
            
            
            
            
      #     def validate_each(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
      #       record.errors.add attribute, (options[:message] || "is not an email") unless
           
        
      
        
          - 
            
            
            
            
      #         /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i.match?(value)
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name, :email
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates :name, presence: true, length: { maximum: 100 }
           
        
      
        
          - 
            
            
            
            
      #     validates :email, presence: true, email: true
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Validator classes may also exist within the class being validated
           
        
      
        
          - 
            
            
            
            
      # allowing custom modules of validators to be included as needed.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Film
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     class TitleValidator < ActiveModel::EachValidator
           
        
      
        
          - 
            
            
            
            
      #       def validate_each(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
      #         record.errors.add attribute, "must start with 'the'" unless /\Athe/i.match?(value)
           
        
      
        
          - 
            
            
            
            
      #       end
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     validates :name, title: true
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Additionally validator classes may be in another namespace and still
           
        
      
        
          - 
            
            
            
            
      # used within any class.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates :name, :'film/title' => true
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # The validators hash can also handle regular expressions, ranges, arrays
           
        
      
        
          - 
            
            
            
            
      # and strings in shortcut form.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates :email, format: /@/
           
        
      
        
          - 
            
            
            
            
      #   validates :role, inclusion: %w(admin contributor)
           
        
      
        
          - 
            
            
            
            
      #   validates :password, length: 6..20
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # When using shortcut form, ranges and arrays are passed to your
           
        
      
        
          - 
            
            
            
            
      # validator's initializer as <tt>options[:in]</tt> while other types
           
        
      
        
          - 
            
            
            
            
      # including regular expressions and strings are passed as <tt>options[:with]</tt>.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # 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
           
        
      
        
          - 
            
            
            
            
      #   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>)
           
        
      
        
          - 
            
            
            
            
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
           
        
      
        
          - 
            
            
            
            
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
           
        
      
        
          - 
            
            
            
            
      #   proc or string should return or evaluate to a +true+ or +false+ value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
           
        
      
        
          - 
            
            
            
            
      #   if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
           
        
      
        
          - 
            
            
            
            
      #   method, proc or string should return or evaluate to a +true+ or
           
        
      
        
          - 
            
            
            
            
      #   +false+ value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_nil</tt> - Skip validation if the attribute is +nil+.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:allow_blank</tt> - Skip validation if the attribute is blank.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:strict</tt> - If the <tt>:strict</tt> option is set to true
           
        
      
        
          - 
            
            
            
            
      #   will raise ActiveModel::StrictValidationFailed instead of adding the error.
           
        
      
        
          - 
            
            
            
            
      #   <tt>:strict</tt> option can also be set to any other exception.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Example:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates :password, presence: true, confirmation: true, if: :password_required?
           
        
      
        
          - 
            
            
            
            
      #   validates :token, length: 24, strict: TokenLengthException
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+
           
        
      
        
          - 
            
            
            
            
      # and +:message+ can be given to one specific validator, as a hash:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
           
        
      
        
          - 
            1
            
            
            
      def validates(*attributes)
           
        
      
        
          - 
            37
            
            
            
        defaults = attributes.extract_options!.dup
           
        
      
        
          - 
            37
            
            
            
        validations = defaults.slice!(*_validates_default_keys)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            37
            
            
            
        raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
           
        
      
        
          - 
            37
            
            
            
        raise ArgumentError, "You need to supply at least one validation" if validations.empty?
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            37
            
            
            
        defaults[:attributes] = attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            37
            
            
            
        validations.each do |key, options|
           
        
      
        
          - 
            43
            
            
            
          key = "#{key.to_s.camelize}Validator"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            43
            
            
            
          begin
           
        
      
        
          - 
            43
            
            
            
            validator = key.include?("::") ? key.constantize : const_get(key)
           
        
      
        
          - 
            
            
            
            
          rescue NameError
           
        
      
        
          - 
            2
            
            
            
            raise ArgumentError, "Unknown validator: '#{key}'"
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            41
            
            
            
          next unless options
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            40
            
            
            
          validates_with(validator, defaults.merge(_parse_validates_options(options)))
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
      # This method is used to define validations that cannot be corrected by end
           
        
      
        
          - 
            
            
            
            
      # users and are considered exceptional. So each validator defined with bang
           
        
      
        
          - 
            
            
            
            
      # or <tt>:strict</tt> option set to <tt>true</tt> will always raise
           
        
      
        
          - 
            
            
            
            
      # <tt>ActiveModel::StrictValidationFailed</tt> instead of adding error
           
        
      
        
          - 
            
            
            
            
      # when validation fails. See <tt>validates</tt> for more information about
           
        
      
        
          - 
            
            
            
            
      # the validation itself.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     attr_accessor :name
           
        
      
        
          - 
            
            
            
            
      #     validates! :name, presence: true
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   person = Person.new
           
        
      
        
          - 
            
            
            
            
      #   person.name = ''
           
        
      
        
          - 
            
            
            
            
      #   person.valid?
           
        
      
        
          - 
            
            
            
            
      #   # => ActiveModel::StrictValidationFailed: Name can't be blank
           
        
      
        
          - 
            1
            
            
            
      def validates!(*attributes)
           
        
      
        
          - 
            1
            
            
            
        options = attributes.extract_options!
           
        
      
        
          - 
            1
            
            
            
        options[:strict] = true
           
        
      
        
          - 
            1
            
            
            
        validates(*(attributes << options))
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    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.
           
        
      
        
          - 
            1
            
            
            
      def _validates_default_keys
           
        
      
        
          - 
            37
            
            
            
        [:if, :unless, :on, :allow_blank, :allow_nil, :strict]
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
      def _parse_validates_options(options)
           
        
      
        
          - 
            40
            
            
            
        case options
           
        
      
        
          - 
            
            
            
            
        when TrueClass
           
        
      
        
          - 
            22
            
            
            
          {}
           
        
      
        
          - 
            
            
            
            
        when Hash
           
        
      
        
          - 
            11
            
            
            
          options
           
        
      
        
          - 
            
            
            
            
        when Range, Array
           
        
      
        
          - 
            2
            
            
            
          { in: options }
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            5
            
            
            
          { with: options }
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/array/extract_options"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            1
            
            
            
  module Validations
           
        
      
        
          - 
            1
            
            
            
    class WithValidator < EachValidator # :nodoc:
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attr, val)
           
        
      
        
          - 
            4
            
            
            
        method_name = options[:with]
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            4
            
            
            
        if record.method(method_name).arity == 0
           
        
      
        
          - 
            2
            
            
            
          record.send method_name
           
        
      
        
          - 
            
            
            
            
        else
           
        
      
        
          - 
            2
            
            
            
          record.send method_name, attr
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    module ClassMethods
           
        
      
        
          - 
            
            
            
            
      # Passes the record off to the class or classes specified and allows them
           
        
      
        
          - 
            
            
            
            
      # to add errors based on more complex conditions.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #     validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
      #     def validate(record)
           
        
      
        
          - 
            
            
            
            
      #       if some_complex_logic
           
        
      
        
          - 
            
            
            
            
      #         record.errors.add :base, 'This record is invalid'
           
        
      
        
          - 
            
            
            
            
      #       end
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #     private
           
        
      
        
          - 
            
            
            
            
      #       def some_complex_logic
           
        
      
        
          - 
            
            
            
            
      #         # ...
           
        
      
        
          - 
            
            
            
            
      #       end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # You may also pass it multiple classes, like so:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #     validates_with MyValidator, MyOtherValidator, on: :create
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # 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
           
        
      
        
          - 
            
            
            
            
      #   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>)
           
        
      
        
          - 
            
            
            
            
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
           
        
      
        
          - 
            
            
            
            
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
           
        
      
        
          - 
            
            
            
            
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>).
           
        
      
        
          - 
            
            
            
            
      #   The method, proc or string should return or evaluate to a +true+ or
           
        
      
        
          - 
            
            
            
            
      #   +false+ value.
           
        
      
        
          - 
            
            
            
            
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
           
        
      
        
          - 
            
            
            
            
      #   determine if the validation should not occur
           
        
      
        
          - 
            
            
            
            
      #   (e.g. <tt>unless: :skip_validation</tt>, or
           
        
      
        
          - 
            
            
            
            
      #   <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
           
        
      
        
          - 
            
            
            
            
      #   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::Validations#validates!</tt> for more information.
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      # If you pass any additional configuration options, they will be passed
           
        
      
        
          - 
            
            
            
            
      # to the class and available as +options+:
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class Person
           
        
      
        
          - 
            
            
            
            
      #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
      #     validates_with MyValidator, my_custom_key: 'my custom value'
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            
            
            
            
      #
           
        
      
        
          - 
            
            
            
            
      #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
      #     def validate(record)
           
        
      
        
          - 
            
            
            
            
      #       options[:my_custom_key] # => "my custom value"
           
        
      
        
          - 
            
            
            
            
      #     end
           
        
      
        
          - 
            
            
            
            
      #   end
           
        
      
        
          - 
            1
            
            
            
      def validates_with(*args, &block)
           
        
      
        
          - 
            377
            
            
            
        options = args.extract_options!
           
        
      
        
          - 
            377
            
            
            
        options[:class] = self
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            377
            
            
            
        args.each do |klass|
           
        
      
        
          - 
            378
            
            
            
          validator = klass.new(options, &block)
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            357
            
            
            
          if validator.respond_to?(:attributes) && !validator.attributes.empty?
           
        
      
        
          - 
            345
            
            
            
            validator.attributes.each do |attribute|
           
        
      
        
          - 
            369
            
            
            
              _validators[attribute.to_sym] << validator
           
        
      
        
          - 
            
            
            
            
            end
           
        
      
        
          - 
            
            
            
            
          else
           
        
      
        
          - 
            12
            
            
            
            _validators[nil] << validator
           
        
      
        
          - 
            
            
            
            
          end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            357
            
            
            
          validate(validator, options)
           
        
      
        
          - 
            
            
            
            
        end
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Passes the record off to the class or classes specified and allows them
           
        
      
        
          - 
            
            
            
            
    # to add errors based on more complex conditions.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     validate :instance_validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def instance_validations
           
        
      
        
          - 
            
            
            
            
    #       validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Please consult the class method documentation for more information on
           
        
      
        
          - 
            
            
            
            
    # creating your own validator.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # You may also pass it multiple classes, like so:
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   class Person
           
        
      
        
          - 
            
            
            
            
    #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     validate :instance_validations, on: :create
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #     def instance_validations
           
        
      
        
          - 
            
            
            
            
    #       validates_with MyValidator, MyOtherValidator
           
        
      
        
          - 
            
            
            
            
    #     end
           
        
      
        
          - 
            
            
            
            
    #   end
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # Standard configuration options (<tt>:on</tt>, <tt>:if</tt> and
           
        
      
        
          - 
            
            
            
            
    # <tt>:unless</tt>), which are available on the class version of
           
        
      
        
          - 
            
            
            
            
    # +validates_with+, should instead be placed on the +validates+ method
           
        
      
        
          - 
            
            
            
            
    # as these are applied and tested in the callback.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    # If you pass any additional configuration options, they will be passed
           
        
      
        
          - 
            
            
            
            
    # to the class and available as +options+, please refer to the
           
        
      
        
          - 
            
            
            
            
    # class version of this method for more information.
           
        
      
        
          - 
            1
            
            
            
    def validates_with(*args, &block)
           
        
      
        
          - 
            2
            
            
            
      options = args.extract_options!
           
        
      
        
          - 
            2
            
            
            
      options[:class] = self.class
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            2
            
            
            
      args.each do |klass|
           
        
      
        
          - 
            2
            
            
            
        validator = klass.new(options, &block)
           
        
      
        
          - 
            2
            
            
            
        validator.validate(self)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require "active_support/core_ext/module/anonymous"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # == Active \Model \Validator
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # A simple base class that can be used along with
           
        
      
        
          - 
            
            
            
            
  # ActiveModel::Validations::ClassMethods.validates_with
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
  #     validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
  #     def validate(record)
           
        
      
        
          - 
            
            
            
            
  #       if some_complex_logic
           
        
      
        
          - 
            
            
            
            
  #         record.errors.add(:base, "This record is invalid")
           
        
      
        
          - 
            
            
            
            
  #       end
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     private
           
        
      
        
          - 
            
            
            
            
  #       def some_complex_logic
           
        
      
        
          - 
            
            
            
            
  #         # ...
           
        
      
        
          - 
            
            
            
            
  #       end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Any class that inherits from ActiveModel::Validator must implement a method
           
        
      
        
          - 
            
            
            
            
  # called +validate+ which accepts a +record+.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
  #     validates_with MyValidator
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
  #     def validate(record)
           
        
      
        
          - 
            
            
            
            
  #       record # => The person instance being validated
           
        
      
        
          - 
            
            
            
            
  #       options # => Any non-standard options passed to validates_with
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # To cause a validation error, you must add to the +record+'s errors directly
           
        
      
        
          - 
            
            
            
            
  # from within the validators message.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
  #     def validate(record)
           
        
      
        
          - 
            
            
            
            
  #       record.errors.add :base, "This is some custom error message"
           
        
      
        
          - 
            
            
            
            
  #       record.errors.add :first_name, "This is some complex validation"
           
        
      
        
          - 
            
            
            
            
  #       # etc...
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # To add behavior to the initialize method, use the following signature:
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
  #     def initialize(options)
           
        
      
        
          - 
            
            
            
            
  #       super
           
        
      
        
          - 
            
            
            
            
  #       @my_custom_field = options[:field_name] || :first_name
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # Note that the validator is initialized only once for the whole application
           
        
      
        
          - 
            
            
            
            
  # life cycle, and not on each validation run.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # The easiest way to add custom validators for validating individual attributes
           
        
      
        
          - 
            
            
            
            
  # is with the convenient <tt>ActiveModel::EachValidator</tt>.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class TitleValidator < ActiveModel::EachValidator
           
        
      
        
          - 
            
            
            
            
  #     def validate_each(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
  #       record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # This can now be used in combination with the +validates+ method
           
        
      
        
          - 
            
            
            
            
  # (see <tt>ActiveModel::Validations::ClassMethods.validates</tt> for more on this).
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class Person
           
        
      
        
          - 
            
            
            
            
  #     include ActiveModel::Validations
           
        
      
        
          - 
            
            
            
            
  #     attr_accessor :title
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #     validates :title, presence: true, title: true
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # It can be useful to access the class that is using that validator when there are prerequisites such
           
        
      
        
          - 
            
            
            
            
  # as an +attr_accessor+ being present. This class is accessible via <tt>options[:class]</tt> in the constructor.
           
        
      
        
          - 
            
            
            
            
  # To set up your validator override the constructor.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  #   class MyValidator < ActiveModel::Validator
           
        
      
        
          - 
            
            
            
            
  #     def initialize(options={})
           
        
      
        
          - 
            
            
            
            
  #       super
           
        
      
        
          - 
            
            
            
            
  #       options[:class].attr_accessor :custom_attribute
           
        
      
        
          - 
            
            
            
            
  #     end
           
        
      
        
          - 
            
            
            
            
  #   end
           
        
      
        
          - 
            1
            
            
            
  class Validator
           
        
      
        
          - 
            1
            
            
            
    attr_reader :options
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the kind of the validator.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   PresenceValidator.kind   # => :presence
           
        
      
        
          - 
            
            
            
            
    #   AcceptanceValidator.kind # => :acceptance
           
        
      
        
          - 
            1
            
            
            
    def self.kind
           
        
      
        
          - 
            5
            
            
            
      @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Accepts options that will be made available through the +options+ reader.
           
        
      
        
          - 
            1
            
            
            
    def initialize(options = {})
           
        
      
        
          - 
            376
            
            
            
      @options = options.except(:class).freeze
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns the kind for this validator.
           
        
      
        
          - 
            
            
            
            
    #
           
        
      
        
          - 
            
            
            
            
    #   PresenceValidator.new(attributes: [:username]).kind # => :presence
           
        
      
        
          - 
            
            
            
            
    #   AcceptanceValidator.new(attributes: [:terms]).kind  # => :acceptance
           
        
      
        
          - 
            1
            
            
            
    def kind
           
        
      
        
          - 
            5
            
            
            
      self.class.kind
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Override this method in subclasses with validation logic, adding errors
           
        
      
        
          - 
            
            
            
            
    # to the records +errors+ array where necessary.
           
        
      
        
          - 
            1
            
            
            
    def validate(record)
           
        
      
        
          - 
            
            
            
            
      raise NotImplementedError, "Subclasses must implement a validate(record) method."
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # +EachValidator+ is a validator which iterates through the attributes given
           
        
      
        
          - 
            
            
            
            
  # in the options hash invoking the <tt>validate_each</tt> method passing in the
           
        
      
        
          - 
            
            
            
            
  # record, attribute and value.
           
        
      
        
          - 
            
            
            
            
  #
           
        
      
        
          - 
            
            
            
            
  # All \Active \Model validations are built on top of this validator.
           
        
      
        
          - 
            1
            
            
            
  class EachValidator < Validator #:nodoc:
           
        
      
        
          - 
            1
            
            
            
    attr_reader :attributes
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Returns a new validator instance. All options will be available via the
           
        
      
        
          - 
            
            
            
            
    # +options+ reader, however the <tt>:attributes</tt> option will be removed
           
        
      
        
          - 
            
            
            
            
    # and instead be made available through the +attributes+ reader.
           
        
      
        
          - 
            1
            
            
            
    def initialize(options)
           
        
      
        
          - 
            366
            
            
            
      @attributes = Array(options.delete(:attributes))
           
        
      
        
          - 
            366
            
            
            
      raise ArgumentError, ":attributes cannot be blank" if @attributes.empty?
           
        
      
        
          - 
            365
            
            
            
      super
           
        
      
        
          - 
            365
            
            
            
      check_validity!
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Performs validation on the supplied record. By default this will call
           
        
      
        
          - 
            
            
            
            
    # +validate_each+ to determine validity therefore subclasses should
           
        
      
        
          - 
            
            
            
            
    # override +validate_each+ with validation logic.
           
        
      
        
          - 
            1
            
            
            
    def validate(record)
           
        
      
        
          - 
            900
            
            
            
      attributes.each do |attribute|
           
        
      
        
          - 
            939
            
            
            
        value = read_attribute_for_validation(record, attribute)
           
        
      
        
          - 
            939
            
            
            
        next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
           
        
      
        
          - 
            902
            
            
            
        validate_each(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Override this method in subclasses with the validation logic, adding
           
        
      
        
          - 
            
            
            
            
    # errors to the records +errors+ array where necessary.
           
        
      
        
          - 
            1
            
            
            
    def validate_each(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
      raise NotImplementedError, "Subclasses must implement a validate_each(record, attribute, value) method"
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
    # Hook method that gets called by the initializer allowing verification
           
        
      
        
          - 
            
            
            
            
    # that the arguments supplied are valid. You could for example raise an
           
        
      
        
          - 
            
            
            
            
    # +ArgumentError+ when invalid options are supplied.
           
        
      
        
          - 
            1
            
            
            
    def check_validity!
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def read_attribute_for_validation(record, attr_name)
           
        
      
        
          - 
            937
            
            
            
        record.read_attribute_for_validation(attr_name)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            
            
            
            
  # +BlockValidator+ is a special +EachValidator+ which receives a block on initialization
           
        
      
        
          - 
            
            
            
            
  # and call this block for each attribute being validated. +validates_each+ uses this validator.
           
        
      
        
          - 
            1
            
            
            
  class BlockValidator < EachValidator #:nodoc:
           
        
      
        
          - 
            1
            
            
            
    def initialize(options, &block)
           
        
      
        
          - 
            2
            
            
            
      @block = block
           
        
      
        
          - 
            2
            
            
            
      super
           
        
      
        
          - 
            
            
            
            
    end
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
    private
           
        
      
        
          - 
            1
            
            
            
      def validate_each(record, attribute, value)
           
        
      
        
          - 
            8
            
            
            
        @block.call(record, attribute, value)
           
        
      
        
          - 
            
            
            
            
      end
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end
           
        
      
    
  
    
      
        
          - 
            
            
            
            
# frozen_string_literal: true
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
require_relative "gem_version"
           
        
      
        
          - 
            
            
            
            
           
        
      
        
          - 
            1
            
            
            
module ActiveModel
           
        
      
        
          - 
            
            
            
            
  # Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt>
           
        
      
        
          - 
            1
            
            
            
  def self.version
           
        
      
        
          - 
            
            
            
            
    gem_version
           
        
      
        
          - 
            
            
            
            
  end
           
        
      
        
          - 
            
            
            
            
end