lib/super_settings.rb in super_settings-0.0.1.rc3 vs lib/super_settings.rb in super_settings-1.0.0

- old
+ new

@@ -1,10 +1,12 @@ # frozen_string_literal: true require_relative "super_settings/application" require_relative "super_settings/coerce" require_relative "super_settings/configuration" +require_relative "super_settings/context" +require_relative "super_settings/context/rack_middleware" require_relative "super_settings/local_cache" require_relative "super_settings/rest_api" require_relative "super_settings/rack_application" require_relative "super_settings/controller_actions" require_relative "super_settings/attributes" @@ -26,11 +28,11 @@ # # @param key [String, Symbol] # @param default [String] value to return if the setting value is nil # @return [String] def get(key, default = nil) - val = local_cache[key] + val = context_setting(key) val.nil? ? default : val.to_s end # Alias for {#get} to allow using the [] operator to get a setting value. # @@ -44,31 +46,31 @@ # # @param key [String, Symbol] # @param default [Integer] value to return if the setting value is nil # @return [Integer] def integer(key, default = nil) - val = local_cache[key] + val = context_setting(key) (val.nil? ? default : val)&.to_i end # Get a setting value cast to a float. # # @param key [String, Symbol] # @param default [Numeric] value to return if the setting value is nil # @return [Float] def float(key, default = nil) - val = local_cache[key] + val = context_setting(key) (val.nil? ? default : val)&.to_f end # Get a setting value cast to a boolean. # # @param key [String, Symbol] # @param default [Boolean] value to return if the setting value is nil # @return [Boolean] def enabled?(key, default = false) - val = local_cache[key] + val = context_setting(key) Coerce.boolean(val.nil? ? default : val) end # Return true if a setting cast as a boolean evaluates to false. # @@ -83,50 +85,26 @@ # # @param key [String, Symbol] # @param default [Time] value to return if the setting value is nil # @return [Time] def datetime(key, default = nil) - val = local_cache[key] + val = context_setting(key) Coerce.time(val.nil? ? default : val) end # Get a setting value cast to an array of strings. # # @param key [String, Symbol] # @param default [Array] value to return if the setting value is nil # @return [Array] def array(key, default = nil) - val = local_cache[key] + val = context_setting(key) val = default if val.nil? return nil if val.nil? Array(val).collect { |v| v&.to_s } end - # Get setting values cast to a hash. This method can be used to cast the flat setting key/value - # store into a structured data store. It uses a delimiter to define how keys are nested which - # defaults to a dot. - # - # If, for example, you have three keys in you settings +A.B1.C1 = 1+, +A.B1.C2 = 2+, and +A.B2.C3 = 3+, the - # nested structure will be: - # - # +{"A" => {"B1" => {"C1" => 1, "C2" => 2}, "B2" => {"C3" => 3}}}+ - # - # This whole hash would be returned if you called +hash+ without any key. If you called it with the - # key "A.B1", it would return - # - # +{"C1" => 1, "C2" => 2}+ - # - # @param key [String, Symbol] the prefix patter to fetch keys for; default to returning all settings - # @param default [Hash] value to return if the setting value is nil - # @param delimiter [String] the delimiter to use to define nested keys in the hash; defaults to "." - # @return [Hash] - def structured(key = nil, default = nil, delimiter: ".", max_depth: nil) - value = local_cache.structured(key, delimiter: delimiter, max_depth: max_depth) - return (default || {}) if value.empty? - value - end - # Create settings and update the local cache with the values. If a block is given, then the # value will be reverted at the end of the block. This method can be used in tests when you # need to inject a specific value into your settings. # # @param key [String, Symbol] the key to set @@ -146,10 +124,11 @@ setting.value = value begin setting.save! local_cache.load_settings unless local_cache.loaded? local_cache.update_setting(setting) + if block_given? yield end ensure if block_given? @@ -159,10 +138,23 @@ local_cache.update_setting(setting) end end end + # Define a block where settings will remain unchanged. This is useful to + # prevent settings from changing while you are in the middle of a block of + # code that depends on the settings. + def context(&block) + reset_context = Thread.current[:super_settings_context].nil? + begin + Thread.current[:super_settings_context] ||= {} + yield + ensure + Thread.current[:super_settings_context] = nil if reset_context + end + end + # Load the settings from the database into the in memory cache. # # @return [void] def load_settings local_cache.load_settings @@ -227,8 +219,25 @@ private def local_cache @local_cache ||= LocalCache.new(refresh_interval: DEFAULT_REFRESH_INTERVAL) + end + + def current_context + Thread.current[:super_settings_context] + end + + def context_setting(key) + key = key.to_s + context = current_context + if context + unless context.include?(key) + context[key] = local_cache[key] + end + context[key] + else + local_cache[key] + end end end end