rails manage gema cancancan all ability ruby-on-rails ruby migration

ruby on rails - manage - ¿Se pueden usar las migraciones de Can Rails para convertir datos?



rails authentication (4)

Intento convertir una columna en mi aplicación de Rails, por razones de argumento, pretendamos que estoy intentando cambiar la columna de age en la tabla de users por una representación de cadena en lugar de una int.

En mi migración tengo esto;

def.self up add_column :users, :age_text, :string users = User.find(:all) users.each do |u| u.age_text = convert_to_text(u.age) u.save end end def self.convert_to_text(number) #code here to convert 1 to ''one'' etc end

Pero parece que no funciona, ¿es posible que lo que intento aquí sea posible con las migraciones?


Aquí hay un ejemplo de migración que ejecuté para convertir datos. Puede convertirlo fácilmente para usar enteros en lugar de cadenas. Hacer la conversión en SQL es mucho más rápido que cargar cada fila en Rails.

class ConvertCommentTextToText < ActiveRecord::Migration def up add_column :comments, :text_tmp, :text # copy text column execute <<-SQL update comments set text_tmp = text SQL remove_column :comments, :text rename_column :comments, :text_tmp, :text end def down add_column :comments, :text_tmp, :string # copy text column execute <<-SQL update comments set text_tmp = text SQL remove_column :comments, :text rename_column :comments, :text_tmp, :text end end

Y para probarlo:

rake db:migrate rake db:rollback rake db:migrate


Como soy nuevo aquí, no puedo comentar lo anterior, así que agregaré mi propia respuesta.

GENERALMENTE manipular datos en migraciones es una MALA idea. Las migraciones con acceso directo al modelo se pueden estancar si cambia la lógica del modelo.

Imagine en su segunda migración que ha agregado una nueva columna. Desea sembrar esa columna con nuevos datos.

Digamos también que unas semanas más tarde agrega una nueva validación al modelo, una validación que opera en un campo que aún no existe en su segunda migración. si alguna vez construyes la base de datos desde la migración 0, tendrás algunos problemas.

Recomiendo usar migraciones para alterar las columnas y otros medios para administrar los datos de la base de datos, especialmente al pasar a la producción.


Lo que intenta hacer es posible, y yo diría que es lo correcto.

Sin embargo, necesita volver a cargar la información de columna para las clases de modelo que está actualizando en la migración, para que Rails conozca las nuevas columnas. Prueba esto:

def.self up add_column :users, :age_text, :string User.reset_column_information users = User.find(:all) users.each do |u| u.age_text = convert_to_text(u.age) u.save end end

En una nota aparte, tenga en cuenta que si su tabla es grande, hacer actualizaciones una a una llevará mucho tiempo ... Tenga cuidado con eso.


Yo diría que si puede "deshacer" los datos importados al revertir la versión de migración, entonces es apropiado colocar las importaciones en la migración.

Por ejemplo, tengo una migración que configura muchas tablas de búsqueda y otros metadatos. Los datos para estas tablas se completan durante esta fase. A medida que cambian los datos de estas tablas de búsqueda, creo nuevos archivos YAML que almacenan los metadatos y los cargo en las migraciones posteriores (y quitamos los YAMLS, volviendo a cargar el archivo YAML anterior al retroceder una versión de migración). Esto es bastante limpio. Tengo archivos (en diferentes carpetas bien definidas en mi caso) con estos archivos:

002_setup_meta_data.rb 002_meta_data.yaml 007_change_meta_data.rb 007_meta_data.yaml

Si está importando datos de "producción" de otro sistema en tablas transaccionales (no estáticas), entonces diría que usar migraciones no es apropiado. Luego, seguiría el consejo de Brian Hogan sobre el uso de tareas de rake.