我在命名方面很糟糕,但我意识到在我的Rails应用程序中有一组更好的模型名称。有没有办法使用迁移来重命名模型及其对应的表?


当前回答

在Rails 4中,我所要做的就是更改def

def change
  rename_table :old_table_name, :new_table_name
end

我所有的索引都被照顾好了。我不需要通过删除旧索引和添加新索引来手动更新索引。

它也可以用变化来改变指数的上下变化。

其他回答

这里有一个例子:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end

  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

我不得不手动重命名模型声明文件。

编辑:

在Rails 3.1和4中,ActiveRecord::Migration::CommandRecorder知道如何反转rename_table迁移,所以你可以这样做:

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

(你仍然需要手动重命名文件。)

其他答案和评论涵盖了表重命名、文件重命名和代码中的grep。

我想再补充几点注意事项:

让我们使用我今天遇到的一个真实的例子:将一个模型从“Merchant”重命名为“Business”。

Don't forget to change the names of dependent tables and models in the same migration. I changed my Merchant and MerchantStat models to Business and BusinessStat at the same time. Otherwise I'd have had to do way too much picking and choosing when performing search-and-replace. For any other models that depend on your model via foreign keys, the other tables' foreign-key column names will be derived from your original model name. So you'll also want to do some rename_column calls on these dependent models. For instance, I had to rename the 'merchant_id' column to 'business_id' in various join tables (for has_and_belongs_to_many relationship) and other dependent tables (for normal has_one and has_many relationships). Otherwise I would have ended up with columns like 'business_stat.merchant_id' pointing to 'business.id'. Here's a good answer about doing column renames. When grepping, remember to search for singular, plural, capitalized, lowercase, and even UPPERCASE (which may occur in comments) versions of your strings. It's best to search for plural versions first, then singular. That way if you have an irregular plural - such as in my merchants :: businesses example - you can get all the irregular plurals correct. Otherwise you may end up with, for example, 'businesss' (3 s's) as an intermediate state, resulting in yet more search-and-replace. Don't blindly replace every occurrence. If your model names collide with common programming terms, with values in other models, or with textual content in your views, you may end up being too over-eager. In my example, I wanted to change my model name to 'Business' but still refer to them as 'merchants' in the content in my UI. I also had a 'merchant' role for my users in CanCan - it was the confusion between the merchant role and the Merchant model that caused me to rename the model in the first place.

你还需要替换索引:

class RenameOldTableToNewTable< ActiveRecord:Migration
  def self.up
    remove_index :old_table_name, :column_name
    rename_table :old_table_name, :new_table_name
    add_index :new_table_name, :column_name
  end 

  def self.down
    remove_index :new_table_name, :column_name
    rename_table :new_table_name, :old_table_name
    add_index :old_table_name, :column_name
  end
end

并重命名您的文件等,手动的其他答案在这里描述。

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

确保在编写迁移之后可以回滚和前滚。如果您犯了一些错误,并且被试图影响不再存在的东西的迁移所困扰,那么这可能会很棘手。如果不能回滚,最好销毁整个数据库并重新开始。所以要注意你可能需要备份一些东西。

另外:检查schema_db中由has_或belongs_to等定义的其他表中的任何相关列名。你可能也需要编辑这些。

最后,在没有回归测试套件的情况下这样做是愚蠢的。

你可以这样做 执行命令:rails g migration rename_ {old_table_name} {new_table_name}

在编辑文件并将此代码添加到方法中后,将发生更改

Rename_table:{old_table_name},:{new_table_name}

在Rails 4中,我所要做的就是更改def

def change
  rename_table :old_table_name, :new_table_name
end

我所有的索引都被照顾好了。我不需要通过删除旧索引和添加新索引来手动更新索引。

它也可以用变化来改变指数的上下变化。