Rails 6.1.4.1
I'm setting values from an initializer file and when I request a page, I find the object_id
of the configuration changed (and the values lost) unless I do require 'my_library'
in the initializer file. I don't understand why?
app/lib/feature_flags.rb:
class FeatureFlags
class Configuration
include ActiveSupport::Configurable
config_accessor(:my_key) { false }
end
class << self
def configuration
@configuration ||= Configuration.new
end
def configure
yield configuration
end
def enabled?(feature)
puts "#{__FILE__} FeatureFlags.configuration.object_id = #{FeatureFlags.configuration.object_id}"
configuration[feature]
end
end
end
config/initializers/feature_flags.rb:
# require 'feature_flag' # If I uncomment this line, the problem is solved
puts "#{__FILE__} FeatureFlags.configuration.object_id = #{FeatureFlags.configuration.object_id}"
FeatureFlags.configure do |config|
config.my_key = true
end
Output:
1. Run the rails server:
config/initializers/feature_flags.rb FeatureFlags.configuration.object_id = 14720
2. Request some page:
app/lib/feature_flags.rb FeatureFlags.configuration.object_id = 22880
My questions are:
- Why do I need to
require 'feature_flags'
in the initializer for the object_id not to change? I thought Zeitwerk was taking care of this. - Is that how I'm supposed to do (to do it right)?
Thanks for your help!
CodePudding user response:
I found my answer here: https://edgeguides.rubyonrails.org/autoloading_and_reloading_constants.html#use-case-1-during-boot-load-reloadable-code
Why is it not working: because FeatureFlags is a reloadable class, it is replaced by a new object uppon request.
How am I supposed to do it right: wrap my initialization code in a to_prepare
block:
Rails.application.config.to_prepare do
FeatureFlags.configure do |config|
config.my_key = true
end
end