class RailsSettings::Base

Constants

PROTECTED_KEYS
SEPARATOR_REGEXP

Attributes

defined_fields[R]

Public Class Methods

_rails_scope(*args, &block)
Alias for: scope
cache_key() click to toggle source
# File lib/rails-settings/base.rb, line 61
def cache_key
  key_parts = ["rails-settings-cached"]
  key_parts << @cache_prefix.call if @cache_prefix
  key_parts.join("/")
end
cache_prefix(&block) click to toggle source
# File lib/rails-settings/base.rb, line 57
def cache_prefix(&block)
  @cache_prefix = block
end
clear_cache() click to toggle source
# File lib/rails-settings/base.rb, line 31
def clear_cache
  RequestCache.reset
  Rails.cache.delete(cache_key)
end
editable_keys() click to toggle source
# File lib/rails-settings/base.rb, line 71
def editable_keys
  @defined_fields.reject { |field| field[:readonly] }.map { |field| field[:key] }
end
field(key, **opts) click to toggle source
# File lib/rails-settings/base.rb, line 36
def field(key, **opts)
  _define_field(key, **opts)
end
get_field(key) click to toggle source
# File lib/rails-settings/base.rb, line 53
def get_field(key)
  @defined_fields.find { |field| field[:key] == key.to_s } || {}
end
keys() click to toggle source
# File lib/rails-settings/base.rb, line 67
def keys
  @defined_fields.map { |field| field[:key] }
end
readonly_keys() click to toggle source
# File lib/rails-settings/base.rb, line 75
def readonly_keys
  @defined_fields.select { |field| field[:readonly] }.map { |field| field[:key] }
end
scope(*args) { |block| ... } click to toggle source
# File lib/rails-settings/base.rb, line 41
def scope(*args, &block)
  name = args.shift
  body = args.shift
  if body.respond_to?(:call)
    return _rails_scope(name, body, &block)
  end

  @scope = name.to_sym
  yield block
  @scope = nil
end
Also aliased as: _rails_scope

Private Class Methods

_all_settings() click to toggle source
# File lib/rails-settings/base.rb, line 202
def _all_settings
  RequestCache.settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do
    vars = unscoped.select("var, value")
    result = {}
    vars.each { |record| result[record.var] = record.value }
    result.with_indifferent_access
  end
end
_convert_string_to_typeof_value(type, value, separator: nil) click to toggle source
# File lib/rails-settings/base.rb, line 155
def _convert_string_to_typeof_value(type, value, separator: nil)
  return value unless [String, Integer, Float, BigDecimal].include?(value.class)

  case type
  when :boolean
    ["true", "1", 1, true].include?(value)
  when :array
    value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
  when :hash
    value = begin
      YAML.safe_load(value).to_h
    rescue
      {}
    end
    value.deep_stringify_keys!
    ActiveSupport::HashWithIndifferentAccess.new(value)
  when :integer
    value.to_i
  when :float
    value.to_f
  when :big_decimal
    value.to_d
  else
    value
  end
end
_define_field(key, default: nil, type: :string, readonly: false, separator: nil, validates: nil, **opts) click to toggle source
# File lib/rails-settings/base.rb, line 83
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil, validates: nil, **opts)
  key = key.to_s

  raise ProcetedKeyError.new(key) if PROTECTED_KEYS.include?(key)

  @defined_fields ||= []
  @defined_fields << {
    scope: @scope,
    key: key,
    default: default,
    type: type || :string,
    readonly: readonly.nil? ? false : readonly,
    options: opts
  }

  if readonly
    define_singleton_method(key) do
      result = default.is_a?(Proc) ? default.call : default
      send(:_convert_string_to_typeof_value, type, result, separator: separator)
    end
  else
    define_singleton_method(key) do
      val = send(:_value_of, key)
      result = nil
      if !val.nil?
        result = val
      else
        result = default
        result = default.call if default.is_a?(Proc)
      end

      result = send(:_convert_string_to_typeof_value, type, result, separator: separator)

      result
    end

    define_singleton_method("#{key}=") do |value|
      var_name = key

      record = find_by(var: var_name) || new(var: var_name)
      value = send(:_convert_string_to_typeof_value, type, value, separator: separator)

      record.value = value
      record.save!

      value
    end

    if validates
      validates[:if] = proc { |item| item.var.to_s == key }
      send(:validates, key, **validates)

      define_method(:read_attribute_for_validation) do |_key|
        self.value
      end
    end
  end

  if type == :boolean
    define_singleton_method("#{key}?") do
      send(key)
    end
  end

  # delegate instance get method to class for support:
  # setting = Setting.new
  # setting.admin_emails
  define_method(key) do
    self.class.public_send(key)
  end
end
_table_exists?() click to toggle source
# File lib/rails-settings/base.rb, line 192
def _table_exists?
  table_exists?
rescue
  false
end
_value_of(var_name) click to toggle source
# File lib/rails-settings/base.rb, line 182
def _value_of(var_name)
  unless _table_exists?
    # Fallback to default value if table was not ready (before migrate)
    puts "WARNING: table: \"#{table_name}\" does not exist or not database connection, `#{name}.#{var_name}` fallback to returns the default value."
    return nil
  end

  _all_settings[var_name]
end
rails_initialized?() click to toggle source
# File lib/rails-settings/base.rb, line 198
def rails_initialized?
  Rails.application&.initialized?
end

Public Instance Methods

clear_cache() click to toggle source
# File lib/rails-settings/base.rb, line 26
def clear_cache
  self.class.clear_cache
end
value() click to toggle source

get the value field, YAML decoded

# File lib/rails-settings/base.rb, line 16
def value
  # rubocop:disable Security/YAMLLoad
  YAML.load(self[:value]) if self[:value].present?
end
value=(new_value) click to toggle source

set the value field, YAML encoded

# File lib/rails-settings/base.rb, line 22
def value=(new_value)
  self[:value] = new_value.to_yaml
end