def format_value(key, val, data_type = nil)
      # if data_type wasn't passed, then get the data_type from the fields hash
      data_type ||= self.fields[key]

      val = format_operation(key, val, data_type)

      case data_type
      when :object
        val = val.with_indifferent_access if val.is_a?(Hash)
      when :array
        # All "array" types use a collection proxy
        val = val.to_a if val.is_a?(Parse::CollectionProxy) #all objects must be in array form
        val = [val] unless val.is_a?(Array) #all objects must be in array form
        val.compact! #remove any nil
        val = Parse::CollectionProxy.new val, delegate: self, key: key
      when :geopoint
        val = Parse::GeoPoint.new(val) unless val.blank?
      when :file
        val = Parse::File.new(val) unless val.blank?
      when :bytes
        val = Parse::Bytes.new(val) unless val.blank?
      when :integer
        if val.nil? || val.respond_to?(:to_i) == false
          val = nil
        else
          val = val.to_i
        end
      when :boolean
        if val.nil?
          val = nil
        else
          val = val ? true : false
        end
      when :string
        val = val.to_s unless val.blank?
      when :float
        val = val.to_f unless val.blank?
      when :acl
        # ACL types go through a special conversion
          val = ACL.typecast(val, self)
      when :date
        # if it respond to parse_date, then use that as the conversion.
        if val.respond_to?(:parse_date) && val.is_a?(Parse::Date) == false
          val = val.parse_date
          # if the value is a hash, then it may be the Parse hash format for an iso date.
        elsif val.is_a?(Hash) # val.respond_to?(:iso8601)
          val = Parse::Date.parse(val["iso"] || val[:iso])
        elsif val.is_a?(String)
          # if it's a string, try parsing the date
          val = Parse::Date.parse val
        #elsif val.present?
        #  pus "[Parse::Stack] Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
        #   raise ValueError, "Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
        end
      when :timezone
        val = Parse::TimeZone.new(val) if val.present?
      else
        # You can provide a specific class instead of a symbol format
        if data_type.respond_to?(:typecast)
          val = data_type.typecast(val)
        else
          warn "Property :#{key}: :#{data_type} has no valid data type"
          val = val #default
        end
      end
      val
    end
def format_value(key, val, data_type = nil)
      # if data_type wasn't passed, then get the data_type from the fields hash
      data_type ||= self.fields[key]

      val = format_operation(key, val, data_type)

      case data_type
      when :object
        val = val.with_indifferent_access if val.is_a?(Hash)
      when :array
        # All "array" types use a collection proxy
        val = val.to_a if val.is_a?(Parse::CollectionProxy) #all objects must be in array form
        val = [val] unless val.is_a?(Array) #all objects must be in array form
        val.compact! #remove any nil
        val = Parse::CollectionProxy.new val, delegate: self, key: key
      when :geopoint
        val = Parse::GeoPoint.new(val) unless val.blank?
      when :file
        val = Parse::File.new(val) unless val.blank?
      when :bytes
        val = Parse::Bytes.new(val) unless val.blank?
      when :integer
        if val.nil? || val.respond_to?(:to_i) == false
          val = nil
        else
          val = val.to_i
        end
      when :boolean
        if val.nil?
          val = nil
        else
          val = val ? true : false
        end
      when :string
        val = val.to_s unless val.blank?
      when :float
        val = val.to_f unless val.blank?
      when :acl
        # ACL types go through a special conversion
          val = ACL.typecast(val, self)
      when :date
        # if it respond to parse_date, then use that as the conversion.
        if val.respond_to?(:parse_date) && val.is_a?(Parse::Date) == false
          val = val.parse_date
          # if the value is a hash, then it may be the Parse hash format for an iso date.
        elsif val.is_a?(Hash) # val.respond_to?(:iso8601)
          val = Parse::Date.parse(val["iso"] || val[:iso])
        elsif val.is_a?(String)
          # if it's a string, try parsing the date
          val = Parse::Date.parse val
        #elsif val.present?
        #  pus "[Parse::Stack] Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
        #   raise ValueError, "Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
        end
      when :timezone
        val = Parse::TimeZone.new(val) if val.present?
      else
        # You can provide a specific class instead of a symbol format
        if data_type.respond_to?(:typecast)
          val = data_type.typecast(val)
        else
          warn "Property :#{key}: :#{data_type} has no valid data type"
          val = val #default
        end
      end
      val
    end
this method takes an input value and transforms it to the proper local format
 depending on the data type that was set for a particular property key.
 Return the internal representation of a property value for a given data type.
 @param key [Symbol] the name of the property
 @param val [Object] the value to format.
 @param data_type [Symbol] provide a hint to the data_type of this value.
 @return [Object]