sql >> Database teknologi >  >> RDS >> PostgreSQL

Problemer med uendelig tidsinterval i Rails

Du kan ikke gemme Infinity som en del af et tidsinterval i Rails. Jeg tror, ​​det skyldes, at Infinity vil blive indsat som en strengværdi og fortolket som en float, når den trækkes ud af den oprindelige PSQL-oid. Så ethvert datointerval fra Dato -> Float vil ikke være levedygtigt. Men du kan klare at skabe dit eget interval med pseudo (1 million år fra nu) datoer, eller du kan bare bruge to separate datofelter og fortolke dem passende i modellen. Startdato, slutdato.

I Rails 4.2+ kan du gemme en Float::INFINITY-værdi i din datetime-type. Eksempel.

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

Dog end_date vil ikke være en gyldig dato. Du gemmer bare strengen i databasen, og du trækker en float ud når du kalder det.

Her er den faktiske (Rails 4.2) kode, der håndterer det:

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

Igen, du vil ikke være i stand til at sammenligne dato og tid med en float. Men det er nok nemt nok at have et særligt tilfælde for disse to værdier -::Float::INFINITY og ::Float::INFINITY




  1. Sådan gemmer du tom værdi som et heltalsfelt

  2. Automatisk nedlukning af MySQL

  3. mysql count fungerer ikke korrekt?

  4. Hvordan gemmer man en datatabel i databasen?