How can I rename a database column in a Ruby on Ra

2019-01-03 00:24发布

I wrongly named a column hased_password instead of hashed_password.

How do I update the database schema, using migration to rename this column?

25条回答
甜甜的少女心
2楼-- · 2019-01-03 00:53

Update - A close cousin of create_table is change_table, used for changing existing tables. It is used in a similar fashion to create_table but the object yielded to the block knows more tricks. For example:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

This way is more efficient if we do with other alter methods such as: remove/add index/remove index/add column, eg we can do further like:

# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...
查看更多
干净又极端
3楼-- · 2019-01-03 00:54
rename_column :table, :old_column, :new_column

Update:

You'll probably want to create a separate migration to do this. (Rename FixColumnName as you will)

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

Then edit the migration to do your will.

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

An update for Rails 3.1

While, the up and down methods still apply. Rails 3.1 receives a change method that "knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate down method"

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

If you happen to have a whole bunch of columns to rename, or something that would have required repeating the table name over and over again.

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

You could use change_table to keep things a little neater.

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

Thank you, Luke && Turadg, for bringing up the topic.

Then just db:migrate as usual or however you go about your business.


An update for Rails 4

While creating a Migration as for renaming a column, Rails 4 generates a change method instead of up and down as mentioned in the above answer. The generated change method is as below :

$ > rails g migration ChangeColumnName

which will create a migration file similar to this :

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
查看更多
做自己的国王
4楼-- · 2019-01-03 00:54

Some versions of Ruby on Rails support to up/down method to migration and if you have up/down method in your migration, then:

def up
    rename_column :table_name, :column_old_name, :column_new_name
end

def down
    rename_column :table_name, :column_new_name, :column_old_name
end

If you have the change method in your migration, then:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

For more information you can move: Ruby on Rails - Migrations or Active Record Migrations.

查看更多
老娘就宠你
5楼-- · 2019-01-03 00:58

For Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
查看更多
干净又极端
6楼-- · 2019-01-03 00:59

If your code is not shared with other one, then best option is to do just rake db:rollback then edit your column name in migration and rake db:migrate. Thats it

And you can write another migration to rename the column

 def change
    rename_column :table_name, :old_name, :new_name
  end

Thats it.

查看更多
甜甜的少女心
7楼-- · 2019-01-03 00:59

As an alternative option, if you are not married to the idea of migrations, there is a compelling gem for ActiveRecord which will handle the name changes automatically for you, Datamapper style. All you do is change the column name in your model (and make sure you put Model.auto_upgrade! at the bottom of your model.rb) and viola! Database is updated on the fly.

https://github.com/DAddYE/mini_record

Note: You will need to nuke db/schema.rb to prevent conflicts

Still in beta phases and obviously not for everyone but still a compelling choice (I am currently using it in two non-trivial production apps with no issues)

查看更多
登录 后发表回答