Rails迁移在尝试在self.up中创建记录时出现错误

4

我有以下迁移:

def self.up
  add_column :project_statuses, :system_sequence, :integer, :default => 0, :null => false

  ProjectStatus.create :name => 'Declined', :sequence => 35, :system_sequence => 110

  ...
end

但是当我运行rake db:createrake db:migrate命令时,出现以下错误:

==  NewProjectStatuses: migrating =============================================
-- add_column(:project_statuses, :system_sequence, :integer, {:default=>0, :null=>false})
   -> 0.0029s
rake aborted!
An error has occurred, this and all later migrations canceled:

unknown attribute: system_sequence
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1753:in `block in assign_attributes'
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1747:in `each'
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1747:in `assign_attributes'
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1567:in `initialize'
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:508:in `new'
/Users/ttt/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.1.1/lib/active_record/base.rb:508:in `create'
/[working dir]/db/migrate/20100816100139_new_project_statuses.rb:7:in `up'

错误的行号指的是 Project.create :name => ... 这一行。

看起来 add_column 那一行根本没被运行,尽管输出显示它已经被运行了。

再次运行 rake db:migrate 可以顺利地完成迁移。

这是为什么呢?

1个回答

18

add_column 代码块后,尝试调用 ProjectStatus.reset_column_information

Rails 会缓存列信息(包括存在哪些列),我认为你遇到的问题是,你正在创建一个列,但这并不会使 Rails 重置其可用列的缓存。因此,你后面的代码行会失败,因为它认为该列不存在。

我不确定为什么缓存是以这种方式设计的,但这种情况在关于使用 reset_column_information 的示例代码中被明确提到。我认为这很可能是问题所在。

话虽如此,我也基本上同意 Michael Durrant 的看法,即通过迁移填充数据库值的使用。首选方法是将默认/种子数据添加到 rake 任务中(可以在任意时间运行),或将其添加到 seeds.rb 文件中,这与迁移的作用不同,迁移只有当前模式版本旧于指定的迁移时才会运行。


是的,这正是问题所在。谢谢!我可能会将那些有问题的行移动到seeds.rb文件中,但在此之后我需要重构迁移行,因为它需要这些创建行才能工作。 - zlog

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