This project is archived and is in readonly mode.
models are not loaded in migrations when config.threadsafe! is set
- Make a new rails project
- Make a new model, and refer to the model somewhere in the migration
- Enable config.threadsafe! in production mode, and migrate in production mode
ex ruby script/generate resource Test
class CreateTests < ActiveRecord::Migration def self.up Test create_table :tests do |t| t.timestamps end end def self.down drop_table :tests end end
and config/environments/production.rb has
# Enable threaded mode config.threadsafe!
rake db:migrate RAILS_ENV=production produces
(in /Users/andrewroth/Development/test_models_in_migration) == CreateTests: migrating ==================================================== rake aborted! An error has occurred, this and all later migrations canceled: uninitialized constant CreateTests::Test (See full trace by running task with --trace)
without threadsafe! it loads Test correctly.
Comments and changes to this ticket
the threadsafe option in production doesn't load the dependencies, you can configure it to load them with this option in your production.rb just after config.threadsafe!
config.dependency_loading = true
but I don't know how rails can behave with both options enabled in production
@thedarkone take a look at the threadsafe! source code:
# Enable threaded mode. Allows concurrent requests to controller actions and # multiple database connections. Also disables automatic dependency loading # after boot, and disables reloading code on every request, as these are # fundamentally incompatible with thread safety. def threadsafe! self.preload_frameworks = true self.cache_classes = true self.dependency_loading = false self.action_controller.allow_concurrency = true self end
with dependency_loading = false rails doesn't autoload dependencies and models are a dependency of migrations
- State changed from new to wontfix
I don't think there is a good fix here. The real issue is that turning off dependency_loading doesn't allow "magic" loading after boot. I would suggest requiring the models the you need in the migration, or better including the model definition again so the migration doesn't depend on its existence.
- Tag changed from 2.3.2, migrations to 2.3.4, migrations
Could we add a warning about that problem somewhere near the config in environments/production.rb? Or perhaps even in the actual 'const missing' error message? 'This might be caused by the fact that you running your application in threadsafe! mode. Please require all dependencies explictily.
I could set up a proposel version on github, if you guys would support one of these measures.
What I mean is that right now, people are writing migrations that access models. I've done it myself when using a legacy database to get a table name, ex. add_column Person.table_name, ... or maybe to repair some inconsistent data put in by a bug, like orphaned or duplicate rows.
What it comes down to is whether the solution is to make people require models in migrations, or make migration loading work in migrations (when threadsafe! is on). I would say that being able to access models in migration is reasonable, and being widely used right now, so the proper way to fix this is to make model accesses work in migrations. The simplest way I can think of to do that is to disable threadsafe mode when migrating somehow.
Of course, an explanation in the error message is better than nothing though.
I'm experiencing this behavior with rake tasks as well. This would seem to be more problematic since there's no philosophical opposition to referencing models within rake tasks?
My specific scenario is that I have a rake bootstrap task that sets up some default system data. Even when depending on the :environment task to load everything up for me, my models aren't found within the rake task unless explicitly required. Disabling config.threadsafe! fixes the reference issues.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>