【问题标题】:Models not loaded when running migrations and rake tasks in staging environment在暂存环境中运行迁移和 rake 任务时未加载模型
【发布时间】:2013-01-22 15:32:54
【问题描述】:

我正在尝试使用 RAILS_ENV=staging bundle exec rake db:migrate --trace 在 staging 中运行以下迁移

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

迁移文件名为 20130121190404_update_database_for_payments.rb。

这会失败并出现以下错误:

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

现在,奇怪的是

  • 此迁移在我的暂存的本地副本上运行良好 环境
  • 我可以毫无问题地通过 rails 控制台创建计划。

我尝试过使用文件名,但无论我做什么,都会出现同样的错误。

【问题讨论】:

  • RAILS_ENC 是错字,对吗?
  • 除了问题之外,如果您通过db/seeds.rb而不是通过迁移文件为这些表创建数据,那将是更好的设计。
  • 同意,但是通过迁移进行播种是我公司的常见做法。之后可能会改变:)
  • 没错,但您希望每次部署时都运行迁移。您不希望 seed.rb 每次部署时都运行。因此,迁移数据(包括添加种子数据)的一种好方法是在迁移中执行此操作。迁移是幂等的,种子不是。

标签: ruby-on-rails rake rails-migrations


【解决方案1】:

部署包含Plan 模型的代码。正如错误提示的那样,它找不到Plan 模型。

编辑:

为了证明是否确实如此,您可以将以下内容放在失败的迁移的顶部:

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

这将打印 Rails 知道的模型列表。我预测你不会在其中找到Plan。为了满足我的好奇心,您还可以输入:puts Dir.glob("app/models/*.rb").map{|p| p.sub("app/models/","")}

【讨论】:

  • 已经部署好了。存在计划,这也表明它们可以通过控制台创建。
  • 当你说Plans 存在时,我认为你没有不小心将你的模型命名为Plans 而不是Plan
  • 是的,它被命名为Plan。最奇怪的是,这个迁移在本地副本上运行良好,只有在部署时才会失败。
  • 好吧,无论出于何种原因,您的登台应用程序肯定找不到Plan 模型。正如您所说,如果您部署了包含 /models/plan.rbclass Plan &lt; ActiveRecord::Base 声明的代码,这尤其奇怪。
  • 他说可以通过控制台在DB中创建Plan记录。很明显,计划很好。
【解决方案2】:

所以我们发现问题在于我们在暂存中启用了线程安全,因为它将成为 Rails 4 中的标准。 显然自动加载不是线程安全的,这就是未加载模型的原因。 The error is also discussed here. 解决方法是设置以下内容

config.threadsafe! unless $rails_rake_task

Moncef Belyamani here所示。

也可以通过在迁移、种子文件或任何其他失败的 rake 任务中明确要求模型来解决此问题。

【讨论】:

    【解决方案3】:

    抱歉,我只能发布这个。

    迁移用于更改您的数据库架构。数据应该在seeds.rb中创建。

    【讨论】:

    • 我同意,但这是我们目前无法改变的传统做法。
    • 没错,但您希望每次部署时都运行迁移。您不希望 seed.rb 每次部署时都运行。因此,迁移数据(包括添加种子数据)的一种好方法是在迁移中执行此操作。迁移是幂等的,种子不是。
    猜你喜欢
    • 2012-11-20
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 2016-02-13
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多