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

¿Hay alguna manera de cambiar las marcas de tiempo predeterminadas de Rails a Y-m-d H:i:s (en lugar de Y-m-d H:i:s.u) o hacer que laravel ignore la parte decimal de Y-m-d H:i:s.u?

Solución en el lado de Rails

Parece que ActiveRecord utilizado en Rails (5.2) agrega automáticamente segundos decimales hasta 1 ms al guardar created_at y updated_at o cualquier otra columna de marca de tiempo en la base de datos que acepte subsegundos, como se define en el archivo active_record/connection_adapters/abstract/quoting.rb

Una solución es esta. Agregue esta línea en un nivel superior en cualquiera de los archivos que Rails siempre leerá al acceder a un modelo (como el archivo de modelo ApplicationRecord).

Time::DATE_FORMATS[:db] = '%Y-%m-%d %H:%M:%S.000000000'

module ActiveRecord::ConnectionAdapters::Quoting
  alias_method :quoted_date_orig, :quoted_date if ! self.method_defined?(:quoted_date_orig)

  def quoted_date(*rest, **kwd)
    quoted = quoted_date_orig(*rest, **kwd)
    quoted.sub(/(\.\d*)\.\d{6}$/, '\1')
  end
end

Puede confirmarlo desde la consola de Rails, después de crear un nuevo registro,

MyModel.last.created_at.nsec  # => 0

o simplemente acceda a la base de datos directamente para verla.

Advertencia

Este cambio no solo afecta a created_at y updated_at pero también todas las demás columnas de marca de tiempo en la base de datos. Creo que aún puede guardar un valor con una precisión de mseg (o nsec) en dicha columna configurando una Cadena en lugar de una instancia de Tiempo en su instancia de Modelo como my_model.col_msec_desired = "2018-01-02 03:04:05.678"; luego Time::DATE_FORMATS[:db] no se hará referencia al guardar el registro.

Solución potencial en el lado de Laravel

Puede ser complicado al momento de escribir (2018-10-18), pero parece que hay un trabajo en progreso, según un publicación muy reciente de Laracast por cmbertsch01

(Nota:una actualización importante realizada un día después de la publicación original, después del comentario).