Rails:我更新了迁移文件,然后运行了db:migrate命令,但我的架构(schema)没有更新。

24

我想给我的一个表添加额外的字段。

我已经在迁移文件(位于db\migrate下)中添加了该字段,然后运行'rake db:migrate'命令,这个过程没有出现问题。甚至我的文本编辑器显示我的schema.db文件已被更新并需要刷新。

但是,模式文件不包含我的新字段,而且从视图中引用该字段的任何尝试都失败了。

如何解决这个问题?是否可以通过Rails更新表格并添加额外字段,而无需完全删除和重新创建数据库?

7个回答

44

http://guides.rubyonrails.org/migrations.html#changing-existing-migrations

在编写迁移时,偶尔会犯错误。如果已经运行了迁移,则不能仅编辑迁移并再次运行迁移:Rails认为它已经运行了该迁移,因此当您运行rake db:migrate时不会执行任何操作。您必须回滚迁移(例如使用rake db:rollback),编辑您的迁移,然后运行rake db:migrate以运行已纠正的版本。


这对我来说是一个方便的解决方案,因为我的数据库更改还没有被他人使用。但我认为对于许多其他人来说,创建一个新的迁移比回滚您的迁移更安全,因为回滚会撤消迁移对模式所做的修改。但我是Rails的新手,也许有更多经验的人可以解释何时使用哪个选项? - Dennis
4
如果你已经发布了(或提交了,这取决于工作流程)现有的迁移,你应该创建一个新的迁移而不是编辑现有的迁移。另一方面,如果你已经应用了一个新创建的迁移并且在那之后发现自己漏掉了某些东西,你应该回滚并编辑该迁移,以避免出现太多无用的迁移。 - utapyngo

7

在数据库中添加/更改内容时,您应该始终创建新的迁移文件。这就是迁移的目的。迁移文件应该具有执行新更改和撤消更改的能力。这样,如果出现问题或您改变了主意,您可以轻松地回滚到以前的迁移。

以下链接中标记为“迁移的解剖结构”和“编写迁移”的部分可能对您有所帮助。

http://guides.rubyonrails.org/migrations.html


即使听起来很好,我从来没有回滚过。但这是真的,这就是迁移应该做到的好处... - Luis Ortega Araneda

6

我也曾经有类似的经历,我想要更改一个字段的名称,但最终得到的结果却是这样的:

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :commenter
      t.text :body

      # this line adds an integer column called `article_id`.
      t.references :article, index: true

      t.timestamps
    end
  end
end

我改变了

  t.text :body

to

t.text :comment_body

我尝试执行rake命令。
db:migrate

没有任何输出,命令提示符又出现了......我查看了Stack Overflow和这个链接指导我运行rake命令。

db:migrate:redo

无输出

== 20141129044056 CreateComments: reverting ===================================
-- drop_table(:comments)
   -> 0.0000s
== 20141129044056 CreateComments: reverted (0.0886s) ==========================

== 20141129044056 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0040s
== 20141129044056 CreateComments: migrated (0.0040s) ==========================

然后我使用评论者 commenter_body 代替 body 加载我的页面/控制器,它正常加载了。

我认为这也是解决相同问题的方法。我不知道在模型/数据库内部是否存在任何问题(实际上我还是 RoR 的新手,才第三天...)


这是一个非常好的解决方案,可以一举进行回滚并再次迁移。http://edgeguides.rubyonrails.org/active_record_migrations.html#rolling-back - atw

4

2

我通过运行rake db:schema:dump成功地使用后来的迁移重新生成了模式。


0

一旦你运行rake db:migrate命令后就不能再向该文件添加列了。如果要添加特定的列,必须使用rails g migration add_columnname_to_tablename生成一个新的迁移文件,并运行rake db:migrate。就这样 !!!


-1

不知道这是否适用,但值得一试。直接引用自《使用Rails进行敏捷开发,第三版》:

有时,这个schema_migrations表会给你带来问题。例如,如果你在添加任何定义模式语句之前创建迁移源文件并运行db:migrate,数据库将认为它已经更新,并且模式信息表将包含新版本号。
如果你编辑了现有的迁移文件并再次运行db:migrate,Rails将不知道如何应用你的新更改。在这种情况下,最简单的方法通常是删除数据库,重新创建它,并重新运行你的迁移。


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