diff options
-rw-r--r-- | app/controllers/application.rb | 1 | ||||
-rw-r--r-- | app/models/setting.rb | 45 | ||||
-rw-r--r-- | db/migrate/065_add_settings_updated_on.rb | 11 |
3 files changed, 47 insertions, 10 deletions
diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 1bb2eac07..b1e2b3d73 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -32,6 +32,7 @@ class ApplicationController < ActionController::Base end def user_setup + Setting.check_cache if session[:user_id] # existing session User.current = User.find(session[:user_id]) diff --git a/app/models/setting.rb b/app/models/setting.rb index ecca01c28..c09b4bdb3 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -23,25 +23,28 @@ class Setting < ActiveRecord::Base validates_uniqueness_of :name validates_inclusion_of :name, :in => @@available_settings.keys validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting| @@available_settings[setting.name]['format'] == 'int' } - - def self.get(name) - name = name.to_s - setting = find_by_name(name) - setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name - setting - end - + + # Hash used to cache setting values + @cached_settings = {} + @cached_cleared_on = Time.now + + # Returns the value of the setting named name def self.[](name) - get(name).value + value = @cached_settings[name] + value ? value : (@cached_settings[name] = find_or_default(name).value) end def self.[]=(name, value) - setting = get(name) + setting = find_or_default(name) setting.value = (value ? value.to_s : "") + @cached_settings[name] = nil setting.save setting.value end + # Defines getter and setter for each setting + # Then setting values can be read using: Setting.some_setting_name + # or set using Setting.some_setting_name = "some value" @@available_settings.each do |name, params| src = <<-END_SRC def self.#{name} @@ -58,4 +61,26 @@ class Setting < ActiveRecord::Base END_SRC class_eval src, __FILE__, __LINE__ end + + # Checks if settings have changed since the values were read + # and clears the cache hash if it's the case + # Called once per request + def self.check_cache + settings_updated_on = Setting.maximum(:updated_on) + if settings_updated_on && @cached_cleared_on <= settings_updated_on + @cached_settings.clear + @cached_cleared_on = Time.now + logger.info "Settings cache cleared." if logger + end + end + +private + # Returns the Setting instance for the setting named name + # (record found in database or new record with default value) + def self.find_or_default(name) + name = name.to_s + raise "There's no setting named #{name}" unless @@available_settings.has_key?(name) + setting = find_by_name(name) + setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name + end end diff --git a/db/migrate/065_add_settings_updated_on.rb b/db/migrate/065_add_settings_updated_on.rb new file mode 100644 index 000000000..8c5fde33b --- /dev/null +++ b/db/migrate/065_add_settings_updated_on.rb @@ -0,0 +1,11 @@ +class AddSettingsUpdatedOn < ActiveRecord::Migration + def self.up + add_column :settings, :updated_on, :timestamp + # set updated_on + Setting.find(:all).each(&:save) + end + + def self.down + remove_column :settings, :updated_on + end +end |