Cambiar el nombre de las columnas created_at, updated_at de ActiveRecord / Rails

Quiero cambiar el nombre de las columnas de marca de tiempo definidas en timestamp.rb. ¿Pueden sobrescribirse los métodos de timestamp.rb? Y lo que debe hacerse en la aplicación es que se use el módulo con los métodos sobrescritos.

No hay una forma simple de hacer eso. Puede lograr esto anulando el módulo ActiveRecord :: Timestamp, o escribiendo uno propio para hacer la magia por usted.

Así es como funciona la magia.

Esto puede hacerse simplemente escribiendo los métodos del módulo ActiveRecord :: Timestamp. En realidad, no sobrescribe todo el módulo. Necesito lograr este mismo objective ya que estoy trabajando con una base de datos heredada. Estoy en vías 3 y he comenzado a seguir una metodología de cómo parchear mi código con la funcionalidad de escribir sobre Rails.

Primero creo el proyecto base con el que estoy trabajando y creo un archivo llamado eso en los inicializadores. En este caso, creé active_record.rb. Y dentro del archivo puse el código para anular dos métodos que controlaban la marca de tiempo. A continuación está la muestra de mi código:

module ActiveRecord module Timestamp private def timestamp_attributes_for_update #:nodoc: ["updated_at", "updated_on", "modified_at"] end def timestamp_attributes_for_create #:nodoc: ["created_at", "created_on"] end end end 

NOTA: También me gustaría mencionar que este parche de mono para hacer que las cosas funcionen está mal visto y puede fallar en las actualizaciones, así que ten cuidado y sé completamente lo que quieres hacer.

Actualizaciones:

  • Cambie los nombres de columna de marca de tiempo de símbolo a cadena por cambio de API . Gracias Techbrunch por llamarme la atención sobre este cambio en la API.

Creo que el método de NPatel es un enfoque correcto, pero está haciendo demasiado si solo necesitas cambiar #created_at en un solo modelo. Como el módulo Timestamp está incluido en todos los objetos AR, puede anularlo por modelo, no globalmente.

< = Rails 5.0

 class User < ActiveRecord::Base ... private def timestamp_attributes_for_create super << :registered_at end end 

Rails ~> 5.1

  private_class_method def self.timestamp_attributes_for_create super < < :registered_at end end 

Puede usar los métodos beforesave y antes de crear the DateTime.now para sus columnas especificadas.

 class Sample < ActiveRecord::Base before_create :set_time_stamps before_save :set_time_stamps private def set_time_stamps self.created_column = DateTime.now if self.new_record? self.updated_column = DateTime.now end end 

fast feek hack, elaborando a partir de la respuesta de Milan Novota: añada lo siguiente a environment.rb, reemplazando los valores de las constantes CREATED_COL y UPDATED_COL con los nombres de columna deseados:

 module ActiveRecord module Timestamp CREATED_COL = 'created_at' UPDATED_COL = 'updated_at' private def create_with_timestamps #:nodoc: if record_timestamps t = self.class.default_timezone == :utc ? Time.now.utc : Time.now write_attribute(CREATED_COL, t) if respond_to?(CREATED_COL) && send(CREATED_COL).nil? write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL) && send(UPDATED_COL).nil? end create_without_timestamps end def update_with_timestamps(*args) #:nodoc: if record_timestamps && (!partial_updates? || changed?) t = self.class.default_timezone == :utc ? Time.now.utc : Time.now write_attribute(UPDATED_COL, t) if respond_to?(UPDATED_COL) end update_without_timestamps(*args) end end end 

La syntax correcta para hacer esto en Rails 4.2

 class User < ActiveRecord::Base ... private def timestamp_attributes_for_create super << 'date_add' end def timestamp_attributes_for_update super << 'date_update' end end 

O podría simplemente crear sus propias columnas (DateTime) y simplemente establecer manualmente la columna created_at cuando cree y configure la columna updated_at cuando actualice. Eso podría ser más fácil que el truco anterior. Eso es lo que voy a hacer. Mejor aún, actualice los Rails para permitirnos cambiar estos nombres.

Una sol’n que no usa un parche de mono; use el bloque reversible durante su migración:

 class CreateTest < ActiveRecord::Migration def change create_table :test do |t| end # set the timestamp columns default to now() reversible do |dir| dir.up do tables = [ :test ] tables.each do |t| execute <<-SQL ALTER TABLE #{t.to_s} add column created timestamp without time zone default now(); SQL execute <<-SQL ALTER TABLE #{t.to_s} add column updated timestamp without time zone default now(); SQL end end dir.down do # no need to do anything, the rollback will drop the tables end end end end