mirror of
https://github.com/thoughtbot/factory_bot_rails.git
synced 2022-11-09 11:49:18 -05:00
bfee5d8dcc
Alternate fix for #336. We went with #347 instead because the solution in this commit didn't work with Rails 4.2. Since we are no longer supporting Rails 4.2, I think this is a better approach. The original problem 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 Triggering the first factory_bot reload before initializing I18n could cause an error in some cases. We avoided the problem in #347 by adding a conditional to skip reloading factory_bot before the application has initialized. This commit, on the other hand, moves factory_bot reloading from a prepare callback into an `after_initialize` callback. The initialization process is now simplified to: 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. factory_bot loads definitions for the first time. It then runs the reloader to set up the prepare callback to reload factory_bot when the application reloads (for example by calling `reload!` in the console), and to register the reloader to trigger reloads when any factory_bot definition files change. [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
40 lines
721 B
Ruby
40 lines
721 B
Ruby
# frozen_string_literal: true
|
|
|
|
require "factory_bot_rails/definition_file_paths"
|
|
|
|
module FactoryBotRails
|
|
class Reloader
|
|
def initialize(app)
|
|
@app = app
|
|
@paths = DefinitionFilePaths.new(FactoryBot.definition_file_paths)
|
|
end
|
|
|
|
def run
|
|
return unless @paths.any?
|
|
|
|
register_reloader(build_reloader)
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :app
|
|
|
|
def build_reloader
|
|
reloader_class.new(@paths.files, @paths.directories) do
|
|
FactoryBot.reload
|
|
end
|
|
end
|
|
|
|
def reloader_class
|
|
app.config.file_watcher
|
|
end
|
|
|
|
def register_reloader(reloader)
|
|
app.reloader.to_prepare do
|
|
reloader.execute
|
|
end
|
|
|
|
app.reloaders << reloader
|
|
end
|
|
end
|
|
end
|