Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails migration gives error when trying to also create a record in the self.up

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?

like image 248
zlog Avatar asked Dec 02 '22 00:12

zlog


1 Answers

Try calling ProjectStatus.reset_column_information after the add_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.

like image 200
jefflunt Avatar answered Apr 27 '23 13:04

jefflunt