Tengo una tabla en una aplicación Rails con cientos de miles de registros y solo tienen una created_atmarca de tiempo. Estoy agregando la capacidad de editar estos registros, por lo que quiero agregar una updated_atmarca de tiempo a la tabla. En mi migración para agregar la columna, quiero actualizar todas las filas para que la nueva updated_atcoincida con la anterior created_at, ya que ese es el valor predeterminado para las filas recién creadas en Rails. Podría hacer una find(:all)iteración a través de los registros, pero eso llevaría horas debido al tamaño de la tabla. Lo que realmente quiero hacer es:
UPDATE table_name SET updated_at = created_at;
¿Hay una manera mejor de hacerlo en una migración de Rails usando ActiveRecord en lugar de ejecutar SQL sin formato?

Yourmodel.update_all 'update_at=created_at'es mejor, no? También funciona en un telescopio.upseguida dedown" . Así que considérelodef changesolo en su lugar.changemétodo aún no existía, pero en este caso todavía prefiero usar explícitoupydownser más explícito (si desea controlar lo quedowndebe hacer).Puede usar update_all, que funciona de manera muy similar a SQL sin formato . Esas son todas las opciones que tienes.
Por cierto, personalmente, no presto mucha atención a las migraciones. A veces, SQL sin formato es realmente la mejor solución. Generalmente, el código de migraciones no se reutiliza. Esta es una acción de una sola vez, así que no me preocupo por la pureza del código.
fuente
update_allarchivo de migración interno :-) También puede ejecutar SQL sin procesar dentro del archivo de migración. Sin embargo,update_alles un poco más elegante. Ambos funcionarán exactamente igual.update_allno tengo idea de cómo establecer un valor de columna al de otra, como solicitó el OP. Por favor demuestre.Como escribió gregdan, puede 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
UPDATEdeclaración, al menos en Rails 4.fuente
SET'posts'.'email' = 'options', las opciones son una cadena literalUser.update_all('updated_at = created_at')SQL (0.4ms) UPDATE "users" SET updated_at = created_atPuede ejecutar directamente el siguiente comando en su
rails consoleActiveRecord::Base.connection.execute("UPDATE TABLE_NAME SET COL2 = COL1")Por ejemplo: quiero actualizar el sku de mi tabla de elementos con remote_id of items tables. el comando será el siguiente:
ActiveRecord::Base.connection.execute("UPDATE items SET sku = remote_id")fuente
Yourmodelya se puede eliminar. Trate de evitar el uso de modelos en las migraciones.)Esta es una forma general de resolución, sin necesidad de escribir consultas, ya que las consultas están sujetas a riesgos.
class Demo < ActiveRecord::Migration def change add_column :events, :time_zone, :string Test.all.each do |p| p.update_attributes(time_zone: p.check.last.time_zone) end remove_column :sessions, :time_zone end endfuente
Como operación de una sola vez, lo haría en el
rails console. ¿Realmente tomará horas? Quizás si hay millones de registros ...records = ModelName.all; records do |r|; r.update_attributes(:updated_at => r.created_at); r.save!; end;`fuente