From 3b59f9c6c254e34d95d917857ccbe79f6e1104b0 Mon Sep 17 00:00:00 2001 From: masarakki Date: Thu, 25 May 2017 12:18:08 +0900 Subject: [PATCH] fix-cache-returns-nil (#3213) --- app/lib/settings/extend.rb | 2 +- app/lib/settings/scoped_settings.rb | 65 ++++++++++++++++++++++++++--- app/models/setting.rb | 1 - 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/app/lib/settings/extend.rb b/app/lib/settings/extend.rb index 407c3480f0f..884b4987459 100644 --- a/app/lib/settings/extend.rb +++ b/app/lib/settings/extend.rb @@ -5,7 +5,7 @@ module Settings extend ActiveSupport::Concern def settings - ScopedSettings.for_thing(self) + @settings ||= ScopedSettings.new(self) end end end diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb index 82b70d12801..68f97b5ae6f 100644 --- a/app/lib/settings/scoped_settings.rb +++ b/app/lib/settings/scoped_settings.rb @@ -1,14 +1,69 @@ # frozen_string_literal: true module Settings - class ScopedSettings < ::Setting - def self.for_thing(object) + class ScopedSettings + def initialize(object) @object = object - self end - def self.thing_scoped - unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id) + # rubocop:disable Style/MethodMissing + def method_missing(method, *args) + method_name = method.to_s + # set a value for a variable + if method_name[-1] == '=' + var_name = method_name.sub('=', '') + value = args.first + self[var_name] = value + else + # retrieve a value + self[method_name] + end + end + # rubocop:enable Style/MethodMissing + + def respond_to?(_method_name, _include_private = false) + true + end + + def all_as_records + vars = thing_scoped + records = vars.map { |r| [r.var, r] }.to_h + + Setting.send(:default_settings).each do |key, default_value| + next if records.key?(key) || default_value.is_a?(Hash) + records[key] = Setting.new(var: key, value: default_value) + end + + records + end + + def []=(key, value) + key = key.to_s + record = thing_scoped.find_by(var: key) || thing_scoped.new(var: key) + record.value = value + record.save! + + Rails.cache.write(Setting.cache_key(key, @object), value) + value + end + + def [](key) + Rails.cache.fetch(Setting.cache_key(key, @object)) do + db_val = thing_scoped.find_by(var: key.to_s) + if db_val + default_value = Setting.send(:default_settings)[key] + return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) + db_val.value + else + Setting.send(:default_settings)[key] + end + end + end + + protected + + def thing_scoped + Setting.unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id) end end end diff --git a/app/models/setting.rb b/app/models/setting.rb index db16f228b3a..f5c95777af9 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -35,7 +35,6 @@ class Setting < RailsSettings::Base default_settings[key] end end - val end