如何在Ruby on Rails迁移中重命名数据库列?

时间:2010-01-02 16:18:43

标签: ruby-on-rails ruby-on-rails-3 migration

我错误地将列命名为hased_password而不是hashed_password

如何使用迁移重命名此列来更新数据库架构?

29 个答案:

答案 0 :(得分:2203)

rename_column :table, :old_column, :new_column

<强>更新

您可能希望创建单独的迁移来执行此操作。 (重命名FixColumnName)

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

然后编辑迁移以实现您的意愿。

# 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

Rails 3.1的更新

虽然updown方法仍然适用。 Rails 3.1接收change

rails g migration FixColumnName class FixColumnName < ActiveRecord::Migration def change rename_column :table_name, :old_column, :new_column end end 方法
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

如果您碰巧有一大堆要重命名的列,或者需要一遍又一遍地重复表名的内容。

change_table

你可以使用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 让事情变得更整洁。

Luke

谢谢你,Turadg&amp;&amp; db:migrate,用于提出主题。

然后像往常一样Migration或者你开始做生意。


Rails 4的更新

在为重命名列创建change时,Rails 4会生成up方法,而不是downchange,如上面的答案中所述。生成的$ > rails g migration ChangeColumnName 方法如下:

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

将创建类似于此的迁移文件:

{{1}}

答案 1 :(得分:68)

IMO,在这种情况下,更好地使用rake db:rollback。然后编辑您的迁移,再次键入rake db:migrate。但是,如果您希望列中的数据不丢失,请使用rename_column

答案 2 :(得分:27)

如果该列已经填充了数据并且正在生产中,我建议采用一步一步的方法,以避免在等待迁移时停止生产。

首先,我创建一个db迁移来添加带有新名称的列,并使用旧列名中的值填充它们。

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

然后我会做出改变,并将改变投入生产。

git commit -m 'adding columns with correct name'

然后,一旦提交投入生产,我就会跑。

Production $ bundle exec rake db:migrate

然后我将所有引用旧列名的视图/控制器更新为新列名。运行我的测试套件,并提交这些更改。 (确保它在本地工作并首先通过所有测试后!)

git commit -m 'using correct column name instead of old stinky bad column name'

然后我将该提交推向生产。

此时,您可以删除原始列,而无需担心与迁移本身相关的任何停机时间。

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

然后将此最新迁移推送到生产环境并在后台运行bundle exec rake db:migrate

我意识到这一过程涉及到一个过程,但我宁愿这样做而不是生产迁移的问题。

答案 3 :(得分:26)

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Available Transformations

rename_column(table_name, column_name, new_column_name):

重命名列但保留类型和内容。

答案 4 :(得分:17)

运行以下命令创建迁移文件:

rails g migration ChangeHasedPasswordToHashedPassword

然后在db/migrate文件夹中生成的文件中,写下rename_column,如下所示:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end

答案 5 :(得分:14)

来自API:

rename_column(table_name, column_name, new_column_name)

重命名列,但保持类型和内容保持不变。

答案 6 :(得分:12)

某些版本的Ruby on Rails支持上/下迁移方法,如果您在迁移中有up / down方法,那么:

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

如果迁移中有change方法,则:

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

有关详细信息,您可以移动: Ruby on Rails - Migrations Active Record Migrations

答案 7 :(得分:11)

如果您的代码未与其他代码共享,那么最佳选择就是rake db:rollback 然后在迁移和rake db:migrate中修改列名。多数民众赞成

您可以编写另一个迁移来重命名列

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

多数民众赞成。

答案 8 :(得分:8)

如果您需要切换列名,则需要创建占位符以避免重复列名错误。这是一个例子:

class SwitchColumns < ActiveRecord::Migration
  def change
    rename_column :column_name, :x, :holder
    rename_column :column_name, :y, :x
    rename_column :column_name, :holder, :y
  end
end

答案 9 :(得分:7)

作为替代选择,如果您没有与迁移的想法结合,那么ActiveRecord有一个引人注目的宝石,它将自动为您处理名称更改,Datamapper样式。您所做的只是更改模型中的列名称(并确保将 Model.auto_upgrade!放在model.rb的底部)和中提琴!数据库即时更新。

https://github.com/DAddYE/mini_record

注意:您需要核实 db / schema.rb 以防止冲突

仍然处于测试阶段,显然不适合所有人,但仍然是一个令人信服的选择(我目前在两个非平凡的制作应用中使用它而没有任何问题)

答案 10 :(得分:7)

如果当前数据对您不重要,您可以使用以下命令删除原始迁移:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

如果没有引号,则在原始迁移中进行更改,然后通过以下方式再次运行向上迁移:

rake db:migrate

答案 11 :(得分:6)

只需创建一个新的迁移,然后在一个块中使用rename_column,如下所示。

rename_column :your_table_name, :hased_password, :hashed_password

答案 12 :(得分:6)

Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end

答案 13 :(得分:5)

手动我们可以使用以下方法:

我们可以手动编辑迁移,如:

  • 打开app/db/migrate/xxxxxxxxx_migration_file.rb

  • hased_password更新为hashed_password

  • 运行以下命令

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

然后它将删除您的迁移:

$> rake db:migrate:up VERSION=xxxxxxxxx

它会使用更新的更改添加您的迁移。

答案 14 :(得分:4)

生成迁移文件:

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

#创建db / migrate / xxxxxxxxxx.rb

编辑迁移以实现您的意愿。

Template.body.helpers({
    tasks: function(){
      return Tasks.find({})
    }

答案 15 :(得分:4)

$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

打开该迁移文件并修改该文件,如下所示(输入原始table_name

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end

答案 16 :(得分:4)

运行rails g migration ChangesNameInUsers(或您想要命名的任何内容)

打开刚刚生成的迁移文件,并在方法中添加此行(在def changeend之间):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

保存文件,然后在控制台中运行rake db:migrate

查看您的schema.db,了解该名称是否在数据库中实际更改了!

希望这会有所帮助:)

答案 17 :(得分:3)

 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end

答案 18 :(得分:3)

生成Ruby on Rails迁移

$:> rails g migration Fixcolumnname

在迁移文件中插入代码(XXXXXfixcolumnname.rb)

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

答案 19 :(得分:2)

您有两种方法可以做到这一点:

  1. 在此类型中,它会在回滚时自动运行它的反向代码。

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. 对于此类型,它会在rake db:migrate时运行up方法,并在rake db:rollback时运行down方法:

    def self.up
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
    def self.down
      rename_column :table_name,:new_column_name,:old_column_name
    end
    

答案 20 :(得分:2)

打开Ruby on Rails控制台并输入:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column

答案 21 :(得分:1)

我正在使用5.2,并尝试在devise用户上重命名列。

rename_column位对我有用,但是单数:table_name引发了“找不到用户表”错误。复数为我工作。

rails g RenameAgentinUser

然后将迁移文件更改为此:

rename_column :users, :agent?, :agent

:agent在哪里?是旧的列名。

答案 22 :(得分:1)

让我们KISS。它只需要三个简单的步骤。以下适用于 Rails 5.2

1。创建迁移

  • rails g migration RenameNameToFullNameInStudents

  • rails g RenameOldFieldToNewFieldInTableName-这样,以后的代码维护者就可以很清楚地知道。 (表名称使用复数形式。)

2。编辑迁移

# I prefer to explicitly write theandmethods.

# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb

class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
  def up
    # rename_column :table_name, :old_column, :new_column
    rename_column :students, :name, :full_name
  end

  def down
            # Note that the columns are reversed
    rename_column :students, :full_name, :name
  end
end

3。运行您的迁移

rake db:migrate

您将参加比赛!

答案 23 :(得分:1)

在使用PostgreSQL数据库的 Rails 6 应用程序上工作时,我遇到了这个挑战。

这是我修复的方式

在我看来,表名Products旧列SKU,而 new_column 是{{ 1}}:

创建一个迁移文件,其中将包含用于重命名列的命令:

ProductNumber

rails generate migration RenameSKUToProductNumberInProducts 中打开迁移文件:

db/migrate directory

添加用于重命名列的命令:

db/migrate/20201028082344_rename_sku_to_product_number_in_products.rb

保存,然后运行迁移命令:

class RenameSkuToProductNumberInProducts < ActiveRecord::Migration[6.0]
  def change
    # rename_column :table_name, :old_column, :new_column
    rename_column :products, :sku, :product_number
  end
end

您现在可以通过查看架构文件来确认列的重命名:

rails db:migrate

如果您对列的重命名不满意,可以随时回滚:

db/schema.rb

注意:努力在所有被调用的地方将列名修改为新名称。

仅此而已。

我希望这会有所帮助

答案 24 :(得分:1)

您可以编写迁移运行以下命令来更新列名称:

rename_column :your_table_name, :hased_password, :hashed_password

此外,请确保您使用新列名更新代码中旧列名的任何用法。

答案 25 :(得分:0)

只需使用命令

生成迁移
rails g migration rename_hased_password

之后编辑迁移,在更改方法

中添加以下行
rename_column :table, :hased_password, :hashed_password

这应该可以解决问题。

答案 26 :(得分:0)

Rails 5迁移更改

例如:

  

rails g model Student student_name:string age:integer

如果您想将 student_name 列更改为名称

注意: - 如果您没有运行 rails db:migrate

您可以执行以下步骤

  

rails d model Student student_name:string age:integer

这将删除生成的迁移文件,现在您可以更正列名

  

rails g model学生姓名:字符串年龄:整数

如果您迁移(rails db:migrate),请使用以下选项更改列名

  

rails g migration RemoveStudentNameFromStudent student_name:string

     

rails g migration AddNameToStudent name:string

答案 27 :(得分:0)

rails g migration migrationName

因此,您转到生成的迁移并添加:

rename_column :table, :old_column, :new_column

方法

答案 28 :(得分:-1)

更新 - create_table的近亲是change_table,用于更改现有表。它以与create_table类似的方式使用,但产生块的对象知道更多技巧。例如:

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

如果我们使用其他alter方法,例如:remove / add index / remove index / add column,这种方式更有效,例如我们可以做更多的事情:

# 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
#...