1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot_rails.git synced 2022-11-09 11:49:18 -05:00
thoughtbot--factory_bot_rails/spec/factory_bot_rails
Daniel Colson 35bb9409aa
Set up reloading after_initialize
Fixes #336

Before this commit, the initialization process looked like
this:

Rails runs all of the initializers
1. Run the ["factory_bot.set_factory_paths"][set_factory_paths]
initializer
2. Run the ["factory_bot.register_reloader"][register_reloader]
initializer, which sets up a [prepare callback][]
3. Run the [`:run_prepare_callbacks`][] initializer
4. This triggers the factory_bot [prepare callback][], which causes
factory\_bot to [reload][]

Rails runs `after_initialize` callbacks
1. [I18n initializes]
2. factory\_bot [reloads again][] as described in #334

The double reloading of factory_bot in this initialization is not ideal,
but also shouldn't generally cause any problems on its own.

The problems people are having in #336 come from the fact that
I18n gets set up in an `after_initialize` callback, but factory_bot gets
reloaded before the `after_initialize` callbacks are triggered.
If the `FactoryBot.define` block references any code that uses I18n
translations as it loads, that code will raise an error (references
inside other factory_bot methods, or code that uses I18n translations
inside of methods still works fine, since the whole Rails initialization
process would be complete by the time any of that code runs).

This commit moves factory_bot reloading from a prepare callback into an
`after_initialize` callback. This allows us to avoid reloading
factory_bot before I18n is loaded, and also gets rid of that pesky
double reloading of factory_bot.

The new initialization process looks like:

Rails runs all of the initializers
1. Run the ["factory_bot.set_factory_paths"][set_factory_paths]
2. Run the [`:run_prepare_callbacks`][] initializer, which no longer
involves factory_bot

Rails runs `after_intialize` callbacks
1. [I18n initializes]
2. Run the factory_bot reloader, which sets up the prepare callback for
any future prepares (for example calling `reload!` in the console), and
executes the reloader to run the initial `FactoryBot.reload`

[set_factory_paths]: 3815aae2b9/lib/factory_bot_rails/railtie.rb (L17-L19)
[register_reloader]: 3815aae2b9/lib/factory_bot_rails/railtie.rb (L21-L23)
[prepare callback]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L34-L36
[`:run_prepare_callbacks`]: https://github.com/rails/rails/blob/5-2-stable/railties/lib/rails/application/finisher.rb#L62-L64
[reload]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L24-L26
[I18n initializes]: 13e2102517/activesupport/lib/active_support/i18n_railtie.rb (L16-L20)
[reloads again]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/railtie.rb#L25-L27
2019-09-20 14:22:59 -04:00
..
definition_file_paths_spec.rb Do not register a reloader when file paths not exist 2019-04-09 10:39:51 -04:00
railtie_spec.rb Always execute a reload when Rails triggers one (instead of just on update) to prevent doubly-defined constants errors in factories when using Spring 2019-04-05 13:34:15 -04:00
reloader_spec.rb Set up reloading after_initialize 2019-09-20 14:22:59 -04:00