Tengo una tabla en una aplicación Rails con cientos de miles de registros y solo tienen una created_at
marca de tiempo. Estoy agregando la capacidad de editar estos registros, por lo que quiero agregar una updated_at
marca de tiempo a la tabla. En mi migración para agregar la columna, quiero actualizar todas las filas para que la nueva updated_at
coincida 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.up
seguida dedown
" . Así que considérelodef change
solo en su lugar.change
método aún no existía, pero en este caso todavía prefiero usar explícitoup
ydown
ser más explícito (si desea controlar lo quedown
debe 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_all
archivo de migración interno :-) También puede ejecutar SQL sin procesar dentro del archivo de migración. Sin embargo,update_all
es un poco más elegante. Ambos funcionarán exactamente igual.update_all
no 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
UPDATE
declaració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_at
Puede ejecutar directamente el siguiente comando en su
rails console
ActiveRecord::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
Yourmodel
ya 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 end
fuente
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