Rails无故更改schema.rb文件

9
每次我运行rake db:migrate命令时,Rails都会决定更改我的schema.rb文件。在某些情况下,这是完全合理的,但在其他一些情况下,它似乎是毫无理由地这样做。我感到困惑的情况是当我从git拉取一个新的迁移和一个新版本的schema.rb文件,然后运行rake db:migrate命令时。由于新版本的schema.rb文件随着此迁移而来,我不应该更新schema.rb文件。然而,Rails仍然每次都更改它。当发生这种情况时,我发现了一些非常愚蠢的更改,例如:
add_index "my_table", ["column1", "column2"], :name => "index_on_some_columns"

to

add_index "my_table", ["column2", "column1"], :name => "index_on_some_columns"

当这种情况发生时,我只需运行 git checkout db/schema.rb 然后继续我的工作, 但是这让我十分烦恼。它这么做的原因是什么?我该如何阻止它这样做?
编辑:下面是一个 diff 的摘录。
@@ -165,12 +165,11 @@ ActiveRecord::Schema.define(:version => 20130206001907) do
     t.column "updated_at", :datetime
-    t.column "coordinates", :point, :srid => 4326
@@ -200,15 +199,16 @@ ActiveRecord::Schema.define(:version => 20130206001907) do
     t.column "something", :boolean
+    t.column "coordinates", :point, :srid => 4326
+    t.column "random_string", :string
     t.column "remote", :string
-    t.column "random_string", :string
   end

-  add_index "my_table", ["id", "foreign_id"], :name => "index_active_my_table_on_foreign_and_id"
-  add_index "my_table", ["id", "active"], :name => "index_my_table_on_active_and_id"
-  add_index "my_table", ["id", "content_modified_at"], :name => "index_my_table_on_content_modified_at_and_id"
+  add_index "my_table", ["foreign_id", "id"], :name => "index_active_my_table_on_foreign_and_id"
+  add_index "my_table", ["active", "id"], :name => "index_my_table_on_active_and_id"
+  add_index "my_table", ["content_modified_at", "id"], :name => "index_my_table_on_content_modified_at_and_id"

你的迁移文件中如何定义这个索引? - Novae
在多种情况下,迁移会说 add_index:my_table,["column2","column1"],但通过git提供的schema.rb具有相反的排序方式:add_index"my_table",["column1","column2"]。它似乎是一致的,但现在我想知道列的相反排序如何进入代码。这可能很天真,但这是否与同时使用linux/mac有关? - wesdotcool
我通常会将 db/schema.rb 放在 .gitignore 中。 - house9
2个回答

7
自从该迁移附带了新版本的schema.rb文件后,我不应该更新schema.rb。
这是不准确的。
每次Rails运行迁移时,它都会使用数据库作为源来更新schema.rb文件。它不会查看现有的schema.rb文件,只是使用来自数据库的信息并覆盖它。
似乎真正的问题是在两个不同环境(不同的Ruby、Rails、MySQL和操作系统组合)中运行相同的迁移,可能会产生不同的结果,生成一个schema.rb文件。
解决方法是确保每个检查代码的人正在使用相同的软件版本,尽可能实现统一。如果不可能(因为这是Windows vs. Linux vs. Mac之间的差异,而您不想更改操作系统),那么您将不得不处理这种不便。

谢谢你为我澄清这个问题。我得看看能否拼凑出一些东西,以规避如果文件实际上没有更改就不必更改文件的情况! - wesdotcool

2
对我来说,解决方案是先执行rake db:schema:load。然后rake db:migrate就不会无缘无故地更改我的schema.rb了。
注意:执行rake db:schema:load将删除所有现有数据,并根据现有的schema.rb重新创建数据库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接