81

En la primera migración, declaré en una columna content que la cadena Activerecord hizo que fuera una cadena (255) de acuerdo con la gema de anotación.Cambiar un tipo de columna a cadenas más largas en rieles

Después empujo la aplicación heroku, que utiliza Postgres, si entro en la forma en contenido de una cadena más larga que 255 me sale el error

PGError: ERROR: value too long for type character varying(255) 

El problema es que necesito ese contenido a contener una cadena eso es extremadamente largo quizás (texto libre, podría ser miles de caracteres)

  1. ¿Qué variable (es la cadena no es apropiada para esto) sería aceptada?
  2. ¿Cómo se crea una migración para reemplazar el tipo de esa columna

gracias

Respuesta

193

Debe utilizar text con rieles si quieres una cadena sin límite de longitud. Una migración como esta:

def up 
    change_column :your_table, :your_column, :text 
end 
def down 
    # This might cause trouble if you have strings longer 
    # than 255 characters. 
    change_column :your_table, :your_column, :string 
end 

debe solucionar las cosas. Es posible que desee :null => false o algunas otras opciones al final de eso también.

Cuando utiliza una columna string sin un límite explícito, Rails agregará implícitamente :limit => 255. Pero si usa text, obtendrá cualquier tipo de cadena de longitud arbitraria que admita la base de datos. PostgreSQL le permite usar una columna varchar sin una longitud, pero la mayoría de las bases de datos usan un tipo diferente para eso y Rails no sabe acerca de varchar sin una longitud. Tienes que usar text en Rails para obtener un text column en PostgreSQL. No hay diferencia en PostgreSQL entre una columna del tipo text y una del tipo varchar (pero varchar(n)es diferente). Además, si está implementando encima de PostgreSQL, no hay razón para usar :string (AKA varchar), la base de datos trata text y varchar(n) de la misma forma interna, excepto por las restricciones de longitud adicional para varchar(n); solo debe usar varchar(n) (AKA :string) si tiene una restricción externa (como un formulario del gobierno que dice que el campo 432 en el formulario 897/B tendrá 23 caracteres) en el tamaño de la columna.

Como acotación al margen, si está utilizando una columna string en cualquier lugar, siempre se debe especificar el :limit como un recordatorio para sí mismo que hay un límite y usted debe tener una validación en el modelo para asegurarse de que no se supere el límite . Si excede el límite, PostgreSQL se quejará y generará una excepción, MySQL truncará silenciosamente la cadena o se quejará (dependiendo de la configuración del servidor), SQLite lo dejará pasar tal cual y otras bases de datos harán otra cosa (probablemente se queje) .

Además, también debe desarrollar, probar e implementar en la misma base de datos (que generalmente será PostgreSQL en Heroku), incluso debería usar las mismas versiones del servidor de la base de datos. Existen otras diferencias entre las bases de datos (como el comportamiento de GROUP BY) a las que ActiveRecord no lo aislará. Puede que ya estés haciendo esto, pero pensé en mencionarlo de todos modos.

+13

Gran respuesta. Una nota: Rails actualmente no admite change_column con el método change (http://guides.rubyonrails.org/migrations.html#using-the-change-method); si la memoria sirve, crearás una migración irreversible si lo haces. Mejor hacerlo a la vieja usanza con métodos up/down. – poetmountain

+0

@BourbonJockey: tiene sentido que 'change' no pueda revertir automáticamente un cambio de tipo y la [Migrations Guide] (http://guides.rubyonrails.org/migrations.html#anatomy-of-a- migración) dice que "[el método de cambio] Este método es preferido para escribir migraciones constructivas (agregando columnas o tablas)" y 'change_column' no está en la lista a la que apunta, así que creo que tiene razón. Lo arreglé para usar 'arriba'/'abajo' (con una advertencia en 'abajo'), gracias por el aviso. –

+4

Para referencias futuras de otros lectores, la conversión de cadena a texto en Postgres en Heroku de esta manera NO perderá datos. –

0

Si bien la respuesta aceptada es excelente, quería agregar una respuesta aquí que espero que trate mejor la pregunta original de la parte 2 de los carteles, para los no expertos como yo.

  1. How do I create a migration to replace the type of that column

generar la migración andamio

Puede generar una migración de mantener su cambio tecleando en la consola (basta con sustituir el table para su nombre de tablas, y column para usted nombre de la columna)

rails generate migrate change_table_column 

Esto generará la migración del esqueleto dentro de la aplicación Rails/db/migrate/folder. Esta migración es un marcador de posición para su código de migración.

Por ejemplo, yo quiero crear una migración de cambiar el tipo de una columna desde string a text, en una tabla llamada TodoItems:

class ChangeTodoItemsDescription < ActiveRecord::Migration 
    def change 
    # enter code here 
    change_column :todo_items, :description, :text 
    end 
end 

El funcionamiento de su migración

Una vez que haya ingresó el código para cambiar la columna que acaba de ejecutar:

rake db:migrate 

Para aplicar su migrati en. Si comete un error siempre se puede revertir el cambio con:

rake db:rollack 

Arriba y Abajo métodos

las referencias respuesta aceptada UpDown y métodos, en lugar de la más reciente Change método. Desde los raíles 3.2antiguo estilo Los métodos Arriba y Abajo presentan algunas ventajas sobre el nuevo método de Cambio. 'Arriba y Abajo' evite ActiveRecord::IrreversibleMigration exception. Desde el lanzamiento de Rails 4 puede utilizar reversible para evitar este error:

class ChangeProductsPrice < ActiveRecord::Migration 
    def change 
    reversible do |dir| 
     change_table :products do |t| 
     dir.up { t.change :price, :string } 
     dir.down { t.change :price, :integer } 
     end 
    end 
    end 
end 

Disfrute de rieles :)

Cuestiones relacionadas