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