class Setting < ActiveRecord::Base class SettingNotFound < StandardError end belongs_to :settable, :polymorphic => true include Localized validates_presence_of :key, :kind validates :key, :uniqueness => {:scope => [:settable_id, :settable_type, :locale]} field :key index :key field :kind field :group field :integer_value, :integer field :float_value, :float field :text_value, :text field :string_value, :string field :datetime_value, :datetime field :date_value, :date has_attached :file_value def self.kinds [ :string, :integer, :float, :boolean, :text, :datetime, :date, :file ] end def value setting_kind = self.kind # this will break paperclip 'missing.png' feature, but at least # provides a way to check if an attachment is missing if setting_kind == "file" return nil if !file_value? end self.send("#{setting_kind}_value") end def self.get(key, default = nil) cached_settings = Rails.cache.read('fullstack-settings-cache') unless cached_settings cached_settings = {} Setting.all.each do |setting| l = setting.locale g = setting.group k = [g, setting.key].compact.join('/') cached_settings[l] ||= {} cached_settings[l][k] = setting.value if setting.value end Rails.cache.write('fullstack-settings-cache', cached_settings) end localized_settings = cached_settings[I18n.locale.to_s] || {} unlocalized_settings = cached_settings[nil] || {} key_segments = key.to_s.split("/") if key_segments.size == 1 key_segments.unshift("global") end key = key_segments.join("/") localized_settings[key] || unlocalized_settings[key] || default end # using Setting.get is simpler, expecially if you don't want 'autocreate' feature def self.global(key, opts = {}) key = key.to_s autocreate = opts.delete(:autocreate) kind = opts.delete(:kind) || :string default = opts.delete(:default) group = (opts.delete(:group) || "global").to_s options = opts.delete(:options) locale = opts.delete(:locale).try(:to_s) query = where(:key => key, :group => group, :settable_id => nil) if locale query = query.where(:locale => locale) end setting = query.first || ( autocreate && create( :key => key, :locale => locale, :kind => kind, :"#{kind}_value" => default, :group => group, :options => options ) ) raise SettingNotFound.new("Setting `#{[group, key].join('/')}` not found for locale `#{locale || 'any'}`") if !setting setting.value || default end def self.update_global(key, value) s = self.find_by_key_and_settable_id(key.to_s, nil) if s s.update_attributes(:value => value) end end field :options, :text serialize :options, Hash after_save do Rails.cache.delete('fullstack-settings-cache') end end