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

C'è un modo per cambiare i timestamp predefiniti di Rails in Y-m-d H:i:s (invece di Y-m-d H:i:s.u) o fare in modo che laravel ignori la parte decimale di Y-m-d H:i:s.u?

Soluzione sul lato Rails

Sembra che ActiveRecord utilizzato in Rails (5.2) aggiunga automaticamente secondi decimali fino a 1 msec durante il salvataggio di created_at e updated_at o qualsiasi altra colonna Timestamp nel DB che accetta sottosecondi, come definito nel file active_record/connection_adapters/abstract/quoting.rb

Una soluzione è questa. Aggiungi questa riga al livello più alto in qualsiasi file che verrebbe sempre letto da Rails quando accede a un modello (come il file del modello 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

Puoi confermarlo dalla console di Rails, dopo aver creato un nuovo record,

MyModel.last.created_at.nsec  # => 0

o semplicemente accedi direttamente al DB per vederlo.

Avviso

Questa modifica non riguarda solo created_at e updated_at ma anche tutte le altre colonne timestamp nel DB. Penso che tu possa ancora salvare un valore con precisione msec (o nsec) in una tale colonna impostando una stringa anziché un'istanza Time sull'istanza del modello come my_model.col_msec_desired = "2018-01-02 03:04:05.678"; quindi Time::DATE_FORMATS[:db] non verrebbero referenziati durante il salvataggio del record.

Potenziale soluzione nel lato di Laravel

Potrebbe essere complicato nel momento in cui scrivo (18-10-2018), ma sembra che un lavoro sia in corso, secondo un post Laracast molto recente di cmbertsch01

(Nota:un importante aggiornamento effettuato un giorno dopo il post originale, in seguito al commento.)