在轨道中重命名表

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

我试过这行代码:

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

奇怪的是。我知道我第一次让它工作了,但是现在我得到了这个错误: ActiveRecord: : ConnectionAdapters: : SchemaStatments: Module 的未定义方法‘ rename _ table’

有什么需要我安排的吗?

84399 次浏览

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

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


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

.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)撤消迁移。

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

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