调用 rake 任务时无法加载命名空间模型
Cannot load namespaced model when invoking rake task
我有一个调用其他 rake 任务的 rake 任务,所以我的开发数据可以很容易地重置。
第一个rake任务(lib/tasks/populate.rake)
# Rake task to populate development database with test data
# Run it with "rake db:populate"
namespace :db do
desc 'Erase and fill database'
task populate: :environment do
...
Rake::Task['test_data:create_company_plans'].invoke
Rake::Task['test_data:create_companies'].invoke
Rake::Task['test_data:create_users'].invoke
...
end
end
第二个rake任务(lib/tasks/populate_sub_scripts/create_company_plans.rake)
namespace :test_data do
desc 'Create Company Plans'
task create_company_plans: :environment do
Company::ProfilePlan.create!(name: 'Basic', trial_period_days: 30, price_monthly_cents: 4000)
Company::ProfilePlan.create!(name: 'Professional', trial_period_days: 30, price_monthly_cents: 27_500)
Company::ProfilePlan.create!(name: 'Enterprise', trial_period_days: 30, price_monthly_cents: 78_500)
end
end
当我 运行 bin/rake db:populate 然后我得到这个错误
rake aborted! LoadError: Unable to autoload constant
Company::ProfilePlan, expected
/home/.../app/models/company/profile_plan.rb to define it
但是当我 运行 独立执行第二个 rake 任务时,它运行良好。
模型(路径:/home/.../app/models/company/profile_plan.rb)
class Company::ProfilePlan < ActiveRecord::Base
# == Constants ============================================================
# == Attributes ===========================================================
# == Extensions ===========================================================
monetize :price_monthly_cents
# == Relationships ========================================================
has_many :profile_subscriptions
# == Validations ==========================================================
# == Scopes ===============================================================
# == Callbacks ============================================================
# == Class Methods ========================================================
# == Instance Methods =====================================================
end
Rails 5.0.1
Ruby2.4.0
App 刚从 4.2 升级到 5
当我需要整个路径时有效:
require "#{Rails.root}/app/models/company/profile_plan.rb"
但这对我来说似乎很奇怪,因为在错误消息中 rails 具有正确的模型路径。有人知道为什么我在从另一个 rake 任务调用时必须要求该文件吗?
非常感谢
好吧,看起来 rake 并不急于加载,所以当你单独调用 create_company_plans.rake
时它会加载引用的对象,但是当你从另一个 rake 调用它时,它不知道你会需要它们,所以它们没有加载。
你可以看看另一个QA,它与你的相似。
我想也许你不需要要求整个路径,只是:
require 'models/company/profile_plan'
据我了解,您可以通过 reenable
然后 revoke
执行下面给出的任务来解决问题。如果这不起作用,请原谅我。
['test_data:create_company_plans', 'test_data:create_companies'].each do |task|
Rake::Task[task].reenable
Rake::Task[task].invoke
end
关于这个 Whosebug 问题 how-to-run-rake-tasks-from-within-rake-tasks 有更多信息。
我有一个调用其他 rake 任务的 rake 任务,所以我的开发数据可以很容易地重置。
第一个rake任务(lib/tasks/populate.rake)
# Rake task to populate development database with test data
# Run it with "rake db:populate"
namespace :db do
desc 'Erase and fill database'
task populate: :environment do
...
Rake::Task['test_data:create_company_plans'].invoke
Rake::Task['test_data:create_companies'].invoke
Rake::Task['test_data:create_users'].invoke
...
end
end
第二个rake任务(lib/tasks/populate_sub_scripts/create_company_plans.rake)
namespace :test_data do
desc 'Create Company Plans'
task create_company_plans: :environment do
Company::ProfilePlan.create!(name: 'Basic', trial_period_days: 30, price_monthly_cents: 4000)
Company::ProfilePlan.create!(name: 'Professional', trial_period_days: 30, price_monthly_cents: 27_500)
Company::ProfilePlan.create!(name: 'Enterprise', trial_period_days: 30, price_monthly_cents: 78_500)
end
end
当我 运行 bin/rake db:populate 然后我得到这个错误
rake aborted! LoadError: Unable to autoload constant Company::ProfilePlan, expected /home/.../app/models/company/profile_plan.rb to define it
但是当我 运行 独立执行第二个 rake 任务时,它运行良好。
模型(路径:/home/.../app/models/company/profile_plan.rb)
class Company::ProfilePlan < ActiveRecord::Base
# == Constants ============================================================
# == Attributes ===========================================================
# == Extensions ===========================================================
monetize :price_monthly_cents
# == Relationships ========================================================
has_many :profile_subscriptions
# == Validations ==========================================================
# == Scopes ===============================================================
# == Callbacks ============================================================
# == Class Methods ========================================================
# == Instance Methods =====================================================
end
Rails 5.0.1 Ruby2.4.0
App 刚从 4.2 升级到 5
当我需要整个路径时有效:
require "#{Rails.root}/app/models/company/profile_plan.rb"
但这对我来说似乎很奇怪,因为在错误消息中 rails 具有正确的模型路径。有人知道为什么我在从另一个 rake 任务调用时必须要求该文件吗?
非常感谢
好吧,看起来 rake 并不急于加载,所以当你单独调用 create_company_plans.rake
时它会加载引用的对象,但是当你从另一个 rake 调用它时,它不知道你会需要它们,所以它们没有加载。
你可以看看另一个QA,它与你的相似。
我想也许你不需要要求整个路径,只是:
require 'models/company/profile_plan'
据我了解,您可以通过 reenable
然后 revoke
执行下面给出的任务来解决问题。如果这不起作用,请原谅我。
['test_data:create_company_plans', 'test_data:create_companies'].each do |task|
Rake::Task[task].reenable
Rake::Task[task].invoke
end
关于这个 Whosebug 问题 how-to-run-rake-tasks-from-within-rake-tasks 有更多信息。