Ruby On Rails: añadir o eliminar una columna a MYSQL

Hay varias formas de añadir una columna a una tabla de un modelo ya existente en Rails. La más evidente es la de añadirla directamente, sin embargo esto nos obligará a perder el hilo de los cambios en la base de datos de cara a hacer un db:migrate.

Imaginemos el siguiente esquema:

 create_table "cursos", force: true do |t|
    t.string   "nombre"
    t.string   "num_horas"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Supongamos que necesitamos agregar una serie de campos a esta tabla. La manera más "elegante" de hacerlo es utilizar los mecanismos que ya nos proporciona Rails:

sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_medios_to_curso medios:string
 invoke active_record
 create db/migrate/20160317150309_add_medios_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_modalidad_to_curso modalidad:string
 invoke active_record
 create db/migrate/20160317150332_add_modalidad_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_tipo_to_curso tipo:string
 invoke active_record
 create db/migrate/20160317150346_add_tipo_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_horas_to_curso horas:integer
 invoke active_record
 create db/migrate/20160317150401_add_horas_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_precio_to_curso precio:decimal
 invoke active_record
 create db/migrate/20160317150524_add_precio_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_finicio_to_curso finicio:date
 invoke active_record
 create db/migrate/20160317150607_add_finicio_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_ffin_to_curso ffin:date
 invoke active_record
 create db/migrate/20160317150619_add_ffin_to_curso.rb
sergio@sergio-X555LD:/var/www/html/auxiliares$ rails g migration add_anyo_to_curso anyo:integer
 invoke active_record
 create db/migrate/20160317150702_add_anyo_to_curso.rb```

Los tipos a elegir, y su equivalencia con MySQL son los siguientes:

Rails MySQL
:binary blob
:boolean tinyint(1)
:date date
:datetime datetime
:decimal decimal
:float float
:integer int(11)
:string varchar(255)
:text text
:time time
:timestamp datetime

Si ahora hacemos un rake:db migrate, se ñadirán las columnas declaradas a las BD:

sergio@sergio-X555LD:/var/www/html/auxiliares$ rake db:migrate
 == 20160317150309 AddMediosToCurso: migrating =================================
 -- add_column(:cursos, :medios, :string)
 -> 0.0228s
 == 20160317150309 AddMediosToCurso: migrated (0.0229s) ========================```

```== 20160317150332 AddModalidadToCurso: migrating ==============================
 -- add_column(:cursos, :modalidad, :string)
 -> 0.0091s
 == 20160317150332 AddModalidadToCurso: migrated (0.0092s) =====================```

```== 20160317150346 AddTipoToCurso: migrating ===================================
 -- add_column(:cursos, :tipo, :string)
 -> 0.0099s
 == 20160317150346 AddTipoToCurso: migrated (0.0100s) ==========================```

```== 20160317150401 AddHorasToCurso: migrating ==================================
 -- add_column(:cursos, :horas, :integer)
 -> 0.0110s
 == 20160317150401 AddHorasToCurso: migrated (0.0111s) =========================```

```== 20160317150524 AddPrecioToCurso: migrating =================================
 -- add_column(:cursos, :precio, :decimal)
 -> 0.0098s
 == 20160317150524 AddPrecioToCurso: migrated (0.0099s) ========================```

```== 20160317150607 AddFinicioToCurso: migrating ================================
 -- add_column(:cursos, :finicio, :date)
 -> 0.0084s
 == 20160317150607 AddFinicioToCurso: migrated (0.0085s) =======================```

```== 20160317150619 AddFfinToCurso: migrating ===================================
 -- add_column(:cursos, :ffin, :date)
 -> 0.0110s
 == 20160317150619 AddFfinToCurso: migrated (0.0112s) ==========================```

```== 20160317150702 AddAnyoToCurso: migrating =================================== -- add_column(:cursos, :anyo, :integer) -> 0.0116s == 20160317150702 AddAnyoToCurso: migrated (0.0117s) ==========================```

Ahora podemos comprobar que se han creado las columnas en la base de datos:

<img class="alignnone size-full wp-image-1024" src="https://www.sergioperea.net/wp-content/uploads/2016/03/Sin-nombre.png" alt="Sin nombre" width="650" height="245" srcset="https://www.sergioperea.net/wp-content/uploads/2016/03/Sin-nombre.png 650w, https://www.sergioperea.net/wp-content/uploads/2016/03/Sin-nombre-300x113.png 300w" sizes="(max-width: 650px) 100vw, 650px" />

## ¿Y si queremos eliminar una columna?

Al hacer esto, me dí cuenta de que había añadido una columna que ya existía: precio. Por tanto, quería eliminarla. ¿Cómo hacerlo?bs

```html
<code>&lt;span class="pln">rails g migration &lt;/span>&lt;span class="typ">Remove&lt;/span>&lt;span class="pun">..&lt;/span>&lt;span class="typ">From&lt;/span>&lt;span class="pun">..&lt;/span>&lt;span class="pln"> col1&lt;/span>&lt;span class="pun">:&lt;/span>&lt;span class="pln">type col2&lt;/span>&lt;span class="pun">:&lt;/span>&lt;span class="pln">type col3&lt;/span>&lt;span class="pun">:&lt;/span>&lt;span class="pln">type&lt;/span></code>

En nuestro caso:

<span class="pln">rails g migration </span><span class="typ">RemovePrecioFromCursos</span><span class="pln"> precio</span><span class="pun">:</span><span class="pln">decimal</span>

Esto lo que hará será crear el siguiente proceso que se ejecutará durante la migración:

class RemovePrecioFromCursos &lt; ActiveRecord::Migration
 def change
 remove_column :cursos, :precio, :decimal
 end
end