尝试在 self.up 中创建记录时,Rails 迁移会出错
我有以下迁移:
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:create
、rake 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'
错误的行号指的是 项目.创建:名称=> ...
行。
看起来 add_column
行根本没有运行,即使输出显示它已运行。
再次运行 rake db:migrate 可以很好地完成迁移。
这是为什么呢?
I have the following migration:
def self.up
add_column :project_statuses, :system_sequence, :integer, :default => 0, :null => false
ProjectStatus.create :name => 'Declined', :sequence => 35, :system_sequence => 110
...
end
But when I do a rake db:create
, rake db:migrate
, I get the following error:
== 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'
The erroneous line number refers to the Project.create :name => ...
line.
It seems like the add_column
line isn't run at all, even though the output says it is run.
Running a rake db:migrate
again runs through the migrations fine though.
Why is this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试在
add_column
块之后调用ProjectStatus.reset_column_information
。Rails 缓存列信息(包括存在哪些列),我相信您在这里遇到的是您正在创建一个列,但这不会触发 Rails 在可用列列表上重置其缓存。结果,您的以下行失败,因为它认为该列不存在。
我不确定为什么缓存是这样设计的,但是这种事情明确提到在有关使用
reset_column_information
的示例代码中。我认为这很有可能就是问题所在。话虽这么说,我也普遍同意 Michael Durrant 关于通过迁移向数据库填充值的观点。首选方法是将默认/种子数据添加到 rake 任务(可以在任意时间运行)或
seeds.rb
文件中。这与迁移相反,迁移仅在当前架构版本早于指定迁移时运行。Try calling
ProjectStatus.reset_column_information
after theadd_column
block.Rails caches column information (including which columns exist), and I believe what you're hitting here is that you're creating a column, but that doesn't trigger Rails to reset its cache on the list of available columns. As a result, your following line fails, because it doesn't think the column exists.
I'm not sure why the caching is designed this way, but this sort of thing is explicitly mentioned in the example code regarding the use of
reset_column_information
. I think there's a pretty good chance that's the issue.That being said, I also generally agree with Michael Durrant, regarding the use of filling the DB with values via migrations. The preferred method is to add your default/seed data to a rake task (which can be run at any arbitrary time), or your
seeds.rb
file. This is in contrast to a migration, which is only run when the current schema version is older than the specified migration.