-
Type: Improvement
-
Resolution: Fixed
-
Priority: Minor - P4
-
Affects Version/s: 7.0.5
-
Component/s: None
-
None
-
Environment:Mac Catalina, ruby 2.6.5
Rails 6/zeitwerk appears to have changed behavior with respect to eagerly loading classes. This seems to apply at a minimum to rake tasks that depend on :environment.
In Rails 5.2, when a rake task depending on :environment is run (such as db:mongoid:create_indexes), ::Mongoid.models is populated with (seemingly all of) the models defined by the application.
In Rails 6, ::Mongoid.models is empty in the same scenario.
Interestingly, in Rails 5.2 ::Mongoid.models appears to be empty if one executes a Rails console, therefore it appears that eager loading of application classes is configured based on what script/tool/command is invoked and not just which environment is used.
In https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#eager-loading which describes behavior of Rails 6 with zeitwerk, eager loading of classes is claimed to only happen in production environment:
> Eager loading is controlled by the flag config.eager_load, which is enabled by default in production mode.
This change means that, for example, when one runs rake db:mongoid:create_indexes, Mongoid thinks there are no models defined in the application and as a result it does not create any of the indexes defined by the user.
To reproduce this issue one must have an application created with Rails 6, such as https://github.com/mongoid/mongoid-demo/tree/master/rails.
An application that depends on Rails 6 but uses Rails 5.2 defaults gets the classic autoloader and does not exhibit the issue described herein.
Proposed workaround per the comment:
config.autoloader = :classic
The fix appears to run this prior to referencing ::Mongoid.models:
Zeitwerk::Loader.eager_load_all
However, this needs to be conditioned on zeitwerk actually being used as the application's dependency loader.
Todo:
Identify code using Mongoid.models - appears to only be Rake tasks in Mongoid source
Add documentation to Mongoid.models explaining that the model classes must be loaded before they are seen in this list, pointing out the behavior differences between Rails 5 and Rails 6
Add calls to eagerly load all models to Mongoid's rake tasks
(optional) Add an application reproducing the issue as a test case (cf. https://jira.mongodb.org/browse/MONGOID-4661)
- is duplicated by
-
MONGOID-4888 Rake task does not create indexes
- Closed
- related to
-
MONGOID-4661 Test applications that use Mongoid
- Closed
- links to