2011-01-29 69 views
224

Tengo un modelo de usuarios que necesita una columna :email (se me olvidó agregar esa columna durante el andamio inicial).Agregar una columna a una tabla existente en una migración de Rails

Abrí el archivo de migración y agregué t.string :email, hice rake db:migrate, y obtuve un NoMethodError. Luego añadí la línea

add_column :users, :email, :string 

de nuevo rake db:migrate, de nuevo NoMethodError. ¿Me estoy perdiendo un paso aquí?

Editar: aquí está el archivo de migración.

class CreateUsers < ActiveRecord::Migration 
    def self.up 
    add_column :users, :email, :string 
    create_table :users do |t| 
     t.string :username 
     t.string :email 
     t.string :crypted_password 
     t.string :password_salt 
     t.string :persistence_token 

     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :users 
    end 
end 

Respuesta

432

Si ya ha ejecutado su migración original (antes de editarla), entonces necesita generar una nueva migración (rails generate migration add_email_to_users email:string hará el truco). Luego haz un rake db:migrate y ejecutará la nueva migración.

Si aún no ha ejecutado la migración original, simplemente puede editarla, como lo está intentando hacer. Su código de migración es casi perfecto: solo necesita eliminar la línea add_column por completo (ese código intenta agregar una columna a una tabla, antes de que se haya creado la tabla, y su código de creación de tabla ya se ha actualizado para incluir un t.string :email de todos modos).

+4

rails g migration addEmailToUsers también funciona – wheresmycookie

+3

Para que quede claro, usamos el plural? ¿Entonces es 'add_email_to_users' y NO' add_email_to_user'? – Purplejacket

+8

Correcto. Los nombres de tabla en Rails son siempre plurales (para que coincidan con las convenciones de DB). – camdez

3

Cuando he hecho esto, en lugar de tocar el violín la migración original, puedo crear uno nuevo con sólo la columna de la adición en la sección de arriba y una columna caída en la sección de abajo.

Puede cambiar el original y volver a ejecutarlo si migra hacia abajo, pero en este caso creo que se ha realizado una migración que no funcionará correctamente.

Como está publicado actualmente, está agregando la columna y luego creando la tabla.

Si cambia el orden, podría funcionar. O bien, como está modificando una migración existente, simplemente agréguela a la tabla de creación en lugar de hacer una columna de agregar por separado.

21

También se puede hacer

rake db:rollback

si no se ha añadido ningún dato al tables.Then editar el archivo de migración mediante la adición de la columna de correo electrónico a la misma y luego llamar

rake db:migrate

Esto funcionará si tiene los rieles 3.1 en adelante instalados en su sistema.

Una manera mucho más simple de hacerlo es cambiar para que el cambio en el archivo de migración sea como es. use

$rake db:migrate:redo.

Esto revertirá la última migración y la migrará nuevamente.

76

Use este comando en la consola rieles rails generate migration add_fieldname_to_tablename fieldname:string

y

rake db:migrate para ejecutar esta migración

+0

gracias por la descripción del comando. – zerocon

+1

Plus 1 porque nunca logro recordar la sintaxis para generar migraciones ... – Daniel

15

Para agregar una columna que sólo tenía que seguir estos pasos:

  1. rails generate migration add_fieldname_to_tablename fieldname:string

    alternativos

    rails generate migration addFieldnameToTablename

    Una vez que se genera la migración, a continuación, editar la migración y definir todos los atributos que desea que la columna añadida a tener.

    Nota: Los nombres de tabla en Rails son siempre plurales (para que coincidan con las convenciones de DB). ejemplo usando uno de los pasos mencionados anteriormente-

    rails generate migration addEmailToUsers

  2. rake db:migrate

O

  1. Puede cambiar el esquema desde db/schema.rb, Añadir las columnas quieres en la consulta SQL.
  2. Ejecutar este comando: rake db:schema:load

    Advertencia/Nota

    tener en cuenta que, corriendo rake db:schema:load borra automáticamente todos los datos de las tablas.

+0

Lo hice, pero no rehace el "andamio" y agrego la nueva columna. ¿Cómo puedo hacer eso "automágicamente"? –

+0

@ John Wooten, es posible que desee eliminar el andamio y volver a pasar por él. Eliminar las migraciones correspondientes también. –

+0

para agregar una nota: cambiar el esquema sin cambiar la migración puede crear problemas con otros desarrolladores que mantienen la aplicación. – BKSpurgeon

0

Usted puede deshacer la última migración por

rake db:rollback STEP=1 

o deshacer esta migración específica por

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS> 

y editar el archivo, a continuación, ejecute de nuevo rake db:mirgate.

1

También puede forzar a las columnas de tabla en la tabla usando force: true, si la tabla es ya existen.

ejemplo:

ActiveRecord::Schema.define(version: 20080906171750) do 
    create_table "authors", force: true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
end 
1

veces rails generate migration add_email_to_users email:string produce una migración como esto

class AddEmailToUsers < ActiveRecord::Migration[5.0] 
    def change 
    end 
end 

En ese caso, usted tiene que manualmente una línea adicional a change

class AddEmailToUsers < ActiveRecord::Migration[5.0] 
    def change 
    add_column :users, :email, :string 
    end 
end 

Y luego ejecutar rake db:migrate

Cuestiones relacionadas