在Rails中重命名表格


154

我想重命名表格...(任何表格)。

我尝试了以下代码行:

ActiveRecord::ConnectionAdapters::SchemaStatements.rename_table(old_name, new_name)

这是奇怪的事情。我知道我是第一次使用它,但是现在我遇到了这个错误:ActiveRecord :: ConnectionAdapters :: SchemaStatements:Module的未定义方法“ rename_table”

我需要设置一些东西吗?

Answers:


248

您通常会在迁移中执行以下操作:

class RenameFoo < ActiveRecord::Migration
  def self.up
    rename_table :foo, :bar
  end

  def self.down
    rename_table :bar, :foo
  end
end

1
谢谢你的工作!我还是很困惑为什么上一行没有。噢..
Tommy

@Tommy,该rename_table方法在中定义ActiveRecord::ConnectionAdapters::SchemaStatements。它打算混入其他模块中。如果您想直接运行它,我想您可以这样做include ActiveRecord::ConnectionAdapters::SchemaStatements; rename_table :foo, :bar
cam

或者如果您愿意,也可以使用ActiveRecord :: Migration.rename_table(:foo,:bar)。但是迁移效果最好。您是否还想更改模型名称或将模型名称保留为旧名称?如果是这样,您可能想使用“ set_table_name:bar”在ActiveRecord模型中指定表名。
Aditya Sanghi,

1
您也可以通过“更改”方法而不是上下使用新表单进行迁移。示例
MegaTux 2011年

def更改,而不是现代Rails实现中的def self.up / def.self.down。后者将无声地失败。
huertanix

294

请记住,在Rails> = 3.1中可以使用该change方法。

 class RenameOldTableToNewTable < ActiveRecord::Migration
   def change
     rename_table :old_table_name, :new_table_name
   end 
 end

37
这还将把所有索引从迁移:old_table_name:new_table_name
Gavin Miller

7
只是一点评论:也许更改为:old_named_things,:new_named_things以提醒人们ActiveRecord中的表名通常是复数的。
Carpela

24

.rename_table是实例方法,而不是类方法,因此调用Class.method将无法进行。相反,您必须创建该类的实例,然后在该实例上调用方法,如下所示:Class.new.method

[编辑]在这种情况下,ActiveRecord::ConnectionAdapters::SchemaStatements它甚至都不是类(正如cam指出的那样),这意味着您甚至无法按照我上面所说的创建它的实例。即使您使用cam的示例class Foo; include ActiveRecord::ConnectionAdapters::SchemaStatements; def bar; rename_table; end; end;,它仍然无法正常工作,因为rename_table会引发异常。

另一方面,ActiveRecord::ConnectionAdapters::MysqlAdapter 一个类,您可能必须使用该类来重命名表(或SQLite或PostgreSQL,具体取决于您使用的数据库)。现在,碰巧的ActiveRecord::ConnectionAdapters::MysqlAdapter是,已经可以通过进行访问Model.connection,因此您应该可以完全Model.connection.rename_table使用应用程序中的任何模型进行操作。[/编辑]

但是,如果您希望永久重命名表,我建议您使用迁移来完成。这是使用Rails操作数据库结构的简单且首选的方法。方法如下:

# Commandline
rails generate migration rename_my_table

# In db/migrate/[timestamp]_rename_my_table.rb:
class RenameMyTable < ActiveRecord::Migration
  def self.up
    rename_table :my_table, :my_new_table
  end

  def self.down
    rename_table :my_new_table, :my_table
  end
end

然后,可以使用rake db:migrate(调用self.up方法)运行迁移,并使用rake db:rollback(调用方法self.down)撤消迁移。


我同意,rename_table是一个实例方法,但它不是在一个类中定义的,所以你的建议,呼吁Class.new.method将无法正常工作(例如:ActiveRecord::ConnectionAdapters::SchemaStatements.new给出了错误oMethodError: undefined method ActiveRecord的:: ConnectionAdapters :: SchemaStatements新”:Module`
凸轮

1
还值得指出的是,如果您有一个与表关联的模型,则您将重命名,运行rake db:migraterake db:rollback不会重命名model.rb文件。您将需要手动更改model.rb文件。
9monkeys 2012年

1
在较新的Rails版本(例如5.x)中,可以使用change方法来代替self.upself.down,因为Rails也可以通过它执行回滚。因此,仅此代码就足够了:def change rename_table :my_table, :my_new_table end。。。。。顺便说一句:内幕change您的使用以下命令:add_columnadd_indexadd_timestampscreate_tableremove_timestampsrename_columnrename_indexrename_table

2
ActiveRecord::Migration.rename_table(:old_table_name, :new_table_name)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.