722

What's the syntax for dropping a database table column through a Rails migration?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
Ethan
  • 9,558
  • 5
  • 27
  • 24

24 Answers24

1054
remove_column :table_name, :column_name

For instance:

remove_column :users, :hobby

would remove the hobby Column from the users table.

Nick Hammond
  • 11,228
  • 1
  • 19
  • 9
  • 8
    @XåpplI'-I0llwlg'I-Thanks for the comment. The change method can be used to drop a column in Rails 4 applications, but should not be used in Rails 3. I updated my answer accordingly. – Powers Oct 06 '13 at 21:03
  • 9
    You can also use `remove_column :table_name, :column_name, :type, :options` within the `change` method, since if you specify the type reverting the migration is possible. From the documentation: _The `type`and `options` parameters will be ignored if present. It can be helpful to provide these in a migration's `change` method so it can be reverted. In that case, `type` and `options` will be used by add_column._ – Nicolas Jan 24 '14 at 11:55
  • 28
    In Rails4, you can remove a column in the `change` method, but only if you specify the column type. E.g. `remove_column, :table_name, :column_name, :column_type`. Otherwise you'll get the following error when trying to run the migration: `remove_column is only reversible if given a type` – Dennis Mar 26 '14 at 13:35
  • 6
    It might be worth noting in the main answer that [removing a column does not remove the corresponding index if it exists](http://stackoverflow.com/questions/7204476/will-removing-a-column-with-a-rails-migration-remove-indexes-associated-with-the) – sameers Nov 25 '14 at 19:14
410

For older versions of Rails

ruby script/generate migration RemoveFieldNameFromTableName field_name:datatype

For Rails 3 and up

rails generate migration RemoveFieldNameFromTableName field_name:datatype
Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
prabu
  • 6,121
  • 8
  • 35
  • 39
  • 21
    "rails g" can be used as an alternative to "rails generate" – Noz Sep 13 '12 at 21:37
  • 47
    `rails g migration remove_field_name_from_table_name field_name:datatype` also works – Stuart Nelson Nov 01 '12 at 01:49
  • 7
    Note also that `AddXXXtoTTT` an `RemoveXXXFromTTT` may be followed by a white-spaced list of filed_name:data_type, and the appropriate add_column and remove_column statements will be created: `rails g migration RemoveUnusefulFieldsFromUsers hair_color:string favorite_number:integer` removes two attributes using a single migration. Note also that `remove_column` is not supported by `change` method, so you have to write both `up` and `down`. – Claudio Floreani Apr 21 '13 at 12:36
  • 3
    Rails 4 seems to support `change` for this. Rollback works like it should. – Unknown_Guy Sep 27 '13 at 08:58
  • 1
    I don't think you need the `field_name:datatype`. Removing is removing. – Adam Grant Mar 18 '15 at 14:42
  • 2
    @AdamGrant I think that if you are using a `change` method that can be _reverted*_ you'll need to inform the data type (and all other field modifiers), so if you rollback that migration, the field can be correctly recreated. _* When I say reverted, that's in terms of database structure, of course, data from that column obviously will be lost._ – RFVoltolini May 23 '17 at 13:00
  • 1
    @ClaudioFloreani your comment was really helpfull, many thanks – opensource-developer Jul 17 '20 at 15:12
129

Rails 4 has been updated, so the change method can be used in the migration to drop a column and the migration will successfully rollback. Please read the following warning for Rails 3 applications:

Rails 3 Warning

Please note that when you use this command:

rails generate migration RemoveFieldNameFromTableName field_name:datatype

The generated migration will look something like this:

  def up
    remove_column :table_name, :field_name
  end

  def down
    add_column :table_name, :field_name, :datatype
  end

Make sure to not use the change method when removing columns from a database table (example of what you don't want in the migration file in Rails 3 apps):

  def change
    remove_column :table_name, :field_name
  end

The change method in Rails 3 is not smart when it comes to remove_column, so you will not be able to rollback this migration.

Dennis
  • 56,821
  • 26
  • 143
  • 139
Powers
  • 18,150
  • 10
  • 103
  • 108
  • 4
    then run rake db:migrate – roxdurazo Nov 25 '15 at 01:21
  • 1
    @Powers - brilliant and clear answer - would you be able to elaborate on the following: "The change method in Rails 3 is not smart when it comes to remove_column, so you will not be able to rollback this migration." – BenKoshy Mar 22 '16 at 01:24
  • 1
    @BKSpurgeon - In Rails 3, if you use the `change` method, then the `rake db:rollback` command will error out. `rake db:rollback` is basically the opposite of `rake db:migrate`. This bug was fixed in Rails 4 :) – Powers Mar 22 '16 at 16:30
  • 2
    In Rails 4, I tried to rollback a change drop column. It fails and states you must specify data_type (as in your down code in your answer) – rmcsharry May 16 '16 at 11:51
  • 1
    Same problem occured to me as to @rmcsharry. My rails version is 4.2.2 and i used change method. when i tried to rollback, error occured that remove_column is only reversible if given a type. – M. Habib Nov 13 '17 at 07:12
46

In a rails4 app it is possible to use the change method also for removing columns. The third param is the data_type and in the optional forth you can give options. It is a bit hidden in the section 'Available transformations' on the documentation .

class RemoveFieldFromTableName < ActiveRecord::Migration
  def change
    remove_column :table_name, :field_name, :data_type, {}
  end
end
Lars Schirrmeister
  • 2,215
  • 1
  • 22
  • 23
43

There are two good ways to do this:

remove_column

You can simply use remove_column, like so:

remove_column :users, :first_name

This is fine if you only need to make a single change to your schema.

change_table block

You can also do this using a change_table block, like so:

change_table :users do |t|
  t.remove :first_name
end

I prefer this as I find it more legible, and you can make several changes at once.

Here's the full list of supported change_table methods:

http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table

superluminary
  • 47,086
  • 25
  • 151
  • 148
34

Clear & Simple Instructions for Rails 5 & 6

  • WARNING: You will lose data.
  • Warning: the below instructions are for trivial migrations. For complex migrations with e.g. millions of rows, read/write dbs, clusters, this advice is not for you:

1. Create a migration

Run the following command in your terminal:

rails generate migration remove_fieldname_from_tablename fieldname:fieldtype (Table name in plural, as per convention. See the documentation here. )

Example: rails g migration RemoveAcceptedFromQuotes accepted:boolean

2. Check the migration

# db/migrate/20190122035000_remove_accepted_from_quotes.rb
class RemoveAcceptedFromQuotes < ActiveRecord::Migration[5.2]
  # with rails 5.2 you don't need to add a separate "up" and "down" method.
  def change
    remove_column :quotes, :accepted, :boolean
  end
end

3. Run the migration

rake db:migrate or rails db:migrate (they're both the same)

....And then you're off to the races!

BenKoshy
  • 33,477
  • 14
  • 111
  • 80
20

Generate a migration to remove a column such that if it is migrated (rake db:migrate), it should drop the column. And it should add column back if this migration is rollbacked (rake db:rollback).

The syntax:

remove_column :table_name, :column_name, :type

Removes column, also adds column back if migration is rollbacked.

Example:

remove_column :users, :last_name, :string

Note: If you skip the data_type, the migration will remove the column successfully but if you rollback the migration it will throw an error.

Imran Ahmad
  • 2,798
  • 3
  • 28
  • 49
16

in rails 5 you can use this command in the terminal:

rails generate migration remove_COLUMNNAME_from_TABLENAME COLUMNNAME:DATATYPE

for example to remove the column access_level(string) from table users:

rails generate migration remove_access_level_from_users access_level:string

and then run:

rake db:migrate
aschmid
  • 229
  • 3
  • 12
14

You can try the following:

remove_column :table_name, :column_name

(Official documentation)

gotqn
  • 42,737
  • 46
  • 157
  • 243
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
14

Remove Columns For RAILS 5 App

rails g migration Remove<Anything>From<TableName> [columnName:type]

Command above generate a migration file inside db/migrate directory. Snippet blow is one of remove column from table example generated by Rails generator,

class RemoveAgeFromUsers < ActiveRecord::Migration
  def up
    remove_column :users, :age
  end
  def down
    add_column :users, :age, :integer
  end
end

I also made a quick reference guide for Rails which can be found at here.

XY L
  • 25,431
  • 14
  • 84
  • 143
10
rails g migration RemoveXColumnFromY column_name:data_type

X = column name
Y = table name

EDIT

Changed RemoveXColumnToY to RemoveXColumnFromY as per comments - provides more clarity for what the migration is actually doing.

rmcsharry
  • 5,363
  • 6
  • 65
  • 108
eden
  • 1,979
  • 3
  • 16
  • 13
9

To remove the column from table you have to run following migration:

rails g migration remove_column_name_from_table_name column_name:data_type

Then run command:

rake db:migrate
Jai Chauhan
  • 4,035
  • 3
  • 36
  • 62
Koresol
  • 91
  • 1
  • 2
6

remove_column in change method will help you to delete the column from the table.

class RemoveColumn < ActiveRecord::Migration
  def change
    remove_column :table_name, :column_name, :data_type
  end
end

Go on this link for complete reference : http://guides.rubyonrails.org/active_record_migrations.html

Dharmesh Rupani
  • 1,029
  • 2
  • 12
  • 22
6

For removing column from table in just easy 3 steps as follows:

  1. write this command

rails g migration remove_column_from_table_name

after running this command in terminal one file created by this name and time stamp (remove_column from_table_name).

Then go to this file.

  1. inside file you have to write

    remove_column :table_name, :column_name

  2. Finally go to the console and then do

    rake db:migrate

Single Entity
  • 2,925
  • 3
  • 37
  • 66
Karan Bamniya
  • 93
  • 1
  • 7
5

Give below command it will add in migration file on its own

rails g migration RemoveColumnFromModel

After running above command you can check migration file remove_column code must be added there on its own

Then migrate the db

rake db:migrate
prash
  • 121
  • 1
  • 4
5

Step 1: Create a migration

  rails g migration remove_column_name_from_table

Step 2: Change code in file migration just created

rails version < 3

  def change
    remove_column :table_name, :column_name, :datatype
  end

rails version >= 3

  def change
    remove_column :table_name, :column_name
  end

Step 3: Migrate

rake db:migrate
4

Heres one more from rails console

ActiveRecord::Migration.remove_column(:table_name, :column_name)

tenzin dorjee
  • 306
  • 2
  • 11
2

Simply, You can remove column

remove_column :table_name, :column_name

For Example,

remove_column :posts, :comment
Foram
  • 483
  • 5
  • 12
2

first try to create a migration file running the command:

rails g migration RemoveAgeFromUsers age:string

and then on the root directory of the project run the migration running the command:

rails db:migrate
Javad Moradi
  • 866
  • 7
  • 18
2
  1. Mark the column as ignored in the model
class MyModel < ApplicationRecord
  self.ignored_columns = ["my_field"]
end
  1. Generate a migration
$ bin/rails g migration DropMyFieldFromMyModel
  1. Edit the migration
class DropMyFieldFromMyModel < ActiveRecord::Migration[6.1]
  def change
    safety_assured { remove_column :my_table, :my_field }
  end
end
  1. Run the migration
$ bin/rails db:migrate
Fernando Correia
  • 21,803
  • 13
  • 83
  • 116
1

Through
remove_column :table_name, :column_name
in a migration file

You can remove a column directly in a rails console by typing:
ActiveRecord::Base.remove_column :table_name, :column_name

Manh Cuong
  • 101
  • 4
1

Do like this;

rails g migration RemoveColumnNameFromTables column_name:type

I.e. rails g migration RemoveTitleFromPosts title:string

Anyway, Would be better to consider about downtime as well since the ActiveRecord caches database columns at runtime so if you drop a column, it might cause exceptions until your app reboots.

Ref: Strong migration

Nuttapon
  • 101
  • 4
0

you can use rails migration command

rails generate migration RemoveColumnNameFromTableName column_name:column_type

than you can migrate the database:

rails db:migrate
-1

Just run this in the rails console

ActiveRecord::Base.connection.remove_column("table_name", :column_name, :its_data_type)

or

TableName.find_by_sql(“ALTER TABLE table_name DROP column_name”)