2

I am trying to run the following migration in staging with RAILS_ENV=staging bundle exec rake db:migrate --trace

class UpdateDatabaseForPayments < ActiveRecord::Migration
  def change
    # Create the plans
    Plan.create(:name => "Student")
    Plan.create(:name => "Professional")
    Plan.create(:name => "Studio")
    # create_subscription just creates a subscription the user, 
    # nothing out of the ordinary there.
    User.all.each do |u|
      u.create_subscription
    end
  end
end

The migration filename is called 20130121190404_update_database_for_payments.rb.

This fails with the following error:

uninitialized constant UpdateDatabaseForPayments::Plan
/home/ubuntu/apps/teamup/releases/20130121204425/db/migrate/20130121190404_update_database_for_payments.rb:4:in `change'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:407:in `block (2 levels) in migrate'
/home/ubuntu/.rvm/rubies/ruby-1.9.3-p327-turbo/lib/ruby/1.9.1/benchmark.rb:280:in `measure'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:407:in `block in migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/connection_adapters/abstract/connection_pool.rb:129:in `with_connection'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:389:in `migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:528:in `migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:720:in `block (2 levels) in migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:777:in `call'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:777:in `ddl_transaction'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:719:in `block in migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:700:in `each'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:700:in `migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:570:in `up'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/migration.rb:551:in `migrate'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.11/lib/active_record/railties/databases.rake:179:in `block (2 levels) in <top (required)>'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:228:in `call'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:228:in `block in execute'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:223:in `each'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:223:in `execute'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:166:in `block in invoke_with_call_chain'
/home/ubuntu/.rvm/rubies/ruby-1.9.3-p327-turbo/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/task.rb:152:in `invoke'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:143:in `invoke_task'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:101:in `each'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:101:in `block in top_level'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:110:in `run_with_threads'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:95:in `top_level'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:73:in `block in run'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:160:in `standard_exception_handling'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:70:in `run'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/bin/rake:33:in `<top (required)>'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/bin/rake:23:in `load'
/home/ubuntu/apps/teamup/shared/bundle/ruby/1.9.1/bin/rake:23:in `<main>'
Tasks: TOP => db:migrate

Now, the weird thing is that

  • this migration runs just fine on a local copy of my staging environment
  • I can create the plans through the rails console without problems.

I have tried playing around with the name of the file a bit, but same error no matter what I do.

Simon Thordal
  • 893
  • 10
  • 28
  • RAILS_ENC is a typo, correct? – Peter Brown Jan 22 '13 at 15:45
  • 1
    Other than the issue, it would be better design if you create the data for these tables via `db/seeds.rb` and not via a migration file. – Nishant Jan 22 '13 at 15:56
  • Agreed, but seeding through migrations is common practice at my company. Might be changed after this though :) – Simon Thordal Jan 22 '13 at 16:25
  • 1
    True, but you'd like the migrations to run every time you deploy. You would NOT like the seeds.rb to run every time you deploy. So, a nice way to migrate data, including adding seed data, is to do so in a migration. Migrations are idempotent, seeds are not. – hrdwdmrbl Jan 22 '13 at 17:40

3 Answers3

1

Deploy your code that includes the Plan model. It can't find the Plan model, as the error suggests.

Edit:

To prove if this is indeed the case, you could put the following at the top of your failing migration:

Rails.application.eager_load!
ActiveRecord::Base.descendants.each {|d| puts d.name}

This will print a list of models, essentially, that Rails knows about. I'm predicting you won't find Plan amongst them. To satisfy my curiosity you could also put: puts Dir.glob("app/models/*.rb").map{|p| p.sub("app/models/","")}

Mike Campbell
  • 7,921
  • 2
  • 38
  • 51
  • It is deployed already. Plans exist which is also indicated by the fact that they can be created through the console. – Simon Thordal Jan 22 '13 at 16:16
  • When you say `Plans` exist, I take it you haven't accidentally named your model `Plans` instead of `Plan`? – Mike Campbell Jan 22 '13 at 16:35
  • Yeah, it is named Plan. The weirdest thing is that this migration runs fine on a local copy and only fails when deployed. – Simon Thordal Jan 22 '13 at 16:38
  • Well, your staging app definitely can't find the `Plan` model, for whatever reason that may be. Which is especially weird if, as you say, you have deployed your code which includes `/models/plan.rb` with `class Plan < ActiveRecord::Base` declaration in it. – Mike Campbell Jan 22 '13 at 16:58
  • He said that he can create Plan records in the DB through the console. So clearly Plan is fine. – hrdwdmrbl Jan 22 '13 at 17:59
1

So the issue was found to be in us having enabled thread safe in staging as it is going to be standard in Rails 4. Apparently autoloading is not threadsafe and this was the reason models were not loaded. The error is also discussed here. The fix is to set the following

config.threadsafe! unless $rails_rake_task

as shown by Moncef Belyamani here.

It can also be fixed by explicitly requiring your models in your migrations, your seed file or whatever other rake task that is failing.

Simon Thordal
  • 893
  • 10
  • 28
0

Sorry, I couldn't but post this.

enter image description here

Migrations are for changing your DB schema. Data should be created in seeds.rb.

Alex Teut
  • 844
  • 9
  • 20
  • I agree, but this is an inherited practice that we can't change at the moment. – Simon Thordal Jan 22 '13 at 16:25
  • 4
    True, but you'd like the migrations to run every time you deploy. You would NOT like the seeds.rb to run every time you deploy. So, a nice way to migrate data, including adding seed data, is to do so in a migration. Migrations are idempotent, seeds are not. – hrdwdmrbl Jan 22 '13 at 17:36