I ran into this problem where I was getting “uninitialized constant” errors when running rake tasks. These are tasks which had been working and I verified that the proper paths were set (eager_load_paths). When searching I saw information about config.threadsafe! being a problem so I disabled it and the problems vanished. However, I wanted to use config.threadsafe!, specifically for allow_concurrency. So, how to resolve this.
Why not just use allow_concurrency?
Well the other options set by threadsafe! are mostly to disable things which are buggy when using concurrency. So using allow_concurrency by itself seems likely to cause problems.
How about forcing the loading to happen?
You can call the following to force the loading of classes in a particular task:
Rails.application.eager_load!
However, I found this did not fix the tasks, possibly because of not running the before_eager_load hooks.
How about re-enabling dependency_loading?
The following code placed in config/environments/production.rb seemed to fix the problems:
config.threadsafe!
config.dependency_loading = true if $rails_rake_task
But I have to wonder what is the point of even using threadsafe! in a rake task and whether this will introduce any bugs.
How about not call config.threadsafe! when running rake tasks?
This seems to be the best option. In the config/environments/production.rb file this line enables threadsafe! except when being called by a rake task:
config.threadsafe! unless $rails_rake_task
Note that this cannot be in application.rb because $rails_rake_task
has not been set at that point and that this feature is broken on certain versions of Rails.
More information
- config.threadsafe! and resque · Issue #611 · defunkt/resque · GitHub
- Removing config.threadsafe! | Tenderlovemaking
- Getting rake db:seed and config.threadsafe! to play nice « Code Fancy
- Rails 3 rake task can’t find model in production – Stack Overflow
- Enable threadsafe! by default by tarcieri · Pull Request #6685 · rails/rails · GitHub