【问题标题】:Renaming table in rails在rails中重命名表
【发布时间】:2011-06-05 14:55:21
【问题描述】:

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

我试过这行代码:

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

这是奇怪的事情。我知道我第一次让它工作,但现在我得到这个错误:ActiveRecord::ConnectionAdapters::SchemaStatements:Module 的未定义方法`rename_table'

有什么我需要设置的吗?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

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

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

    【讨论】:

    • 这也会将所有索引从:old_table_name迁移到:new_table_name
    • 稍微评论一下:也许改成:old_named_things, :new_named_things 来提醒人们activerecord中的表名通常是复数的。
    【解决方案2】:

    您通常会在迁移中执行此类操作:

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

    【讨论】:

    • 感谢工作!我仍然很困惑为什么上一行没有。哦,好吧..
    • @Tommy,rename_table 方法在ActiveRecord::ConnectionAdapters::SchemaStatements 中定义。它旨在混合到其他模块中。如果你想直接运行它,我想你可以做include ActiveRecord::ConnectionAdapters::SchemaStatements; rename_table :foo, :bar
    • 或者如果您愿意,可以使用 ActiveRecord::Migration.rename_table(:foo,:bar)。但迁移效果最好。您还想更改模型名称还是想保留旧模型名称?如果是这样,您可能希望使用“set_table_name :bar”在 ActiveRecord 模型中指定表名。
    • 您还可以使用新表单进行迁移,使用 'change' 方法而不是 up & down。 example
    • def 更改,而不是现代 Rails 实现中的 def self.up / def.self.down。做后者会默默地失败。
    【解决方案3】:

    .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 new' 用于 ActiveRecord::ConnectionAdapters::SchemaStatements:Module`
    • 另外值得指出的是,如果您有一个与您要重命名的表关联的模型,运行rake db:migraterake db:rollback 将不会重命名model.rb 文件。您将需要手动更改 model.rb 文件。
    • 在较新的 Rails 版本(例如 5.x)中,您可以使用 change 方法代替 self.upself.down ,因为 Rails 也可以通过它执行回滚。所以这个代码就足够了:def changerename_table :my_table, :my_new_tableend。 . . . .顺便说一句:在change 内部,您可以使用这些命令:add_columnadd_indexadd_timestampscreate_tableremove_timestampsrename_columnrename_indexrename_table
    【解决方案4】:
    ActiveRecord::Migration.rename_table(:old_table_name, :new_table_name)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-20
      • 2018-09-12
      • 2013-09-13
      • 2010-10-04
      相关资源
      最近更新 更多