regresar rails migraciones migracion llaves hacer foraneas eliminar deshacer crear comando columna ruby-on-rails activerecord migration timestamp

ruby on rails - migraciones - Actualizar una columna al valor de otra en la migración de Rails



migracion en rails (4)

Como escribió gregdan, puedes usar update_all . Puedes hacer algo como esto:

Model.where(...).update_all(''updated_at = created_at'')

La primera parte es su conjunto típico de condiciones. La última parte dice cómo hacer las asignaciones. Esto producirá una instrucción UPDATE , al menos en Rails 4.

Tengo una tabla en la aplicación de Rails con cientos de miles de registros, y solo tienen una created_at tiempo created_at . Estoy agregando la capacidad de editar estos registros, por lo que quiero agregar una marca de tiempo updated_at a la tabla. En mi migración para agregar la columna, quiero actualizar todas las filas para que el nuevo updated_at coincida con el antiguo created_at , ya que es el predeterminado para las filas recién creadas en Rails. Podría hacer un find(:all) e iterar a través de los registros, pero eso tomaría horas debido al tamaño de la tabla. Lo que realmente quiero hacer es:

UPDATE table_name SET updated_at = created_at;

¿Hay alguna manera más agradable de hacerlo en una migración de Rails utilizando ActiveRecord en lugar de ejecutar SQL sin procesar?


Como una operación de una sola vez, simplemente lo haría en la rails console . ¿Realmente tomará horas? Tal vez si hay millones de registros ...

records = ModelName.all; records do |r|; r.update_attributes(:updated_at => r.created_at); r.save!; end;`


Puede usar update_all que funciona de manera muy similar al SQL sin procesar. Esas son todas las opciones que tiene.

Por cierto, personalmente no le presto mucha atención a las migraciones. A veces, el SQL en bruto es realmente la mejor solución. En general, el código de migraciones no se reutiliza. Esta es una acción única, así que no me preocupo por la pureza del código.


Yo crearía una migración

rails g migration set_updated_at_values

y dentro de ella escribe algo como:

class SetUpdatedAt < ActiveRecord::Migration def self.up Yourmodel.update_all("updated_at=created_at") end def self.down end end

De esta forma logras dos cosas

  • este es un proceso repetible, con cada despliegue posible (cuando sea necesario) se ejecuta
  • esto es eficiente No puedo pensar en una solución más rubios (que sea tan eficiente).

Nota: también puede ejecutar sql sin formato dentro de una migración, si la consulta se vuelve demasiado difícil de escribir con activerecord. Simplemente escribe lo siguiente:

Yourmodel.connection.execute("update your_models set ... <complicated query> ...")