sql >> Base de Datos >  >> RDS >> PostgreSQL

Problemas con el rango de tiempo infinito en Rails

No puede almacenar Infinity como parte de un rango de tiempo en Rails. Creo que esto se debe a que Infinity se insertará como un valor de cadena y se interpretará como un flotador cuando se extraiga del oid nativo de PSQL. Por lo tanto, cualquier rango de fechas desde Fecha -> Flotante no será viable. Pero puede administrar para crear su propio rango con pseudo (1 millón de años a partir de ahora) fechas o simplemente puede usar dos campos de fecha separados e interpretarlos adecuadamente en el modelo. Fecha de inicio, fecha de finalización.

En Rails 4.2+, puede almacenar un valor Float::INFINITY dentro de su tipo de fecha y hora. Ejemplo.

User.first.update(begin_date: DateTime.now, end_date: 'infinity')
User.first.end_date # => Infinity

Sin embargo, end_date no será una fecha válida. Solo estás almacenando la cadena en la base de datos y está sacando un flotador cuando lo llames.

Aquí está el código real (Rails 4.2) que maneja eso:

module ActiveRecord
  module ConnectionAdapters
    module PostgreSQL
      module OID # :nodoc:
        class DateTime < Type::DateTime # :nodoc:
          include Infinity

          def type_cast_for_database(value)
            if has_precision? && value.acts_like?(:time) && value.year <= 0
              bce_year = format("%04d", -value.year + 1)
              super.sub(/^-?\d+/, bce_year) + " BC"
            else
              super
            end
          end

          def cast_value(value)
            if value.is_a?(::String)
              case value
              when 'infinity' then ::Float::INFINITY
              when '-infinity' then -::Float::INFINITY
              when / BC$/
                astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
                super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
              else
                super
              end
            else
              value
            end
          end
        end
      end
    end
  end
end

De nuevo, no ser capaz de hacer comparaciones de fecha y hora con un flotador. Pero, probablemente sea bastante simple tener un caso especial para estos dos valores -::Float::INFINITY y ::Float::INFINITY