Project

General

Profile

Download (3.41 KB) Statistics
| Branch: | Tag: | Revision:
76607ed5 Ohad Levy
class Setting < ActiveRecord::Base
attr_accessible :name, :value, :description, :category, :settings_type, :default
29eebabc Ohad Levy
# audit the changes to this model
eec062e6 Ohad Levy
audited :only => [:value], :on => [:update]
76607ed5 Ohad Levy
TYPES= %w{ integer boolean hash array }
FROZEN_ATTRS = %w{ name default description category settings_type }
validates_presence_of :name, :description
67799065 Ohad Levy
validates_presence_of :default, :unless => Proc.new { |s| !s.default } # broken validator
76607ed5 Ohad Levy
validates_uniqueness_of :name
validates_numericality_of :value, :if => Proc.new {|s| s.settings_type == "integer"}
d3f6859e Florian Koch
validates_numericality_of :value, :if => Proc.new {|s| s.name == "puppet_interval"}, :greater_than => 0
76607ed5 Ohad Levy
validates_inclusion_of :value, :in => [true,false], :if => Proc.new {|s| s.settings_type == "boolean"}
validates_inclusion_of :settings_type, :in => TYPES, :allow_nil => true, :allow_blank => true
29eebabc Ohad Levy
before_validation :fix_types
76607ed5 Ohad Levy
before_save :save_as_settings_type
validate :validate_attributes
1462d569 Ohad Levy
default_scope :order => 'LOWER(settings.name)'
76607ed5 Ohad Levy
scoped_search :on => :name, :complete_value => :true
scoped_search :on => :category, :complete_value => :true
scoped_search :on => :description, :complete_value => :true

017e1049 Ohad Levy
def self.per_page; 20 end # can't use our own settings
c45a0014 Ohad Levy
76607ed5 Ohad Levy
def self.[](name)
d9a2ebac Ohad Levy
name = name.to_s
cache.fetch name do
where(:name => name).first.try(:value)
76607ed5 Ohad Levy
end
end

def self.[]=(name, value)
d9a2ebac Ohad Levy
name = name.to_s
record = find_or_create_by_name name
76607ed5 Ohad Levy
record.value = value
d9a2ebac Ohad Levy
cache.delete(name)
29eebabc Ohad Levy
record.save!
76607ed5 Ohad Levy
end

def self.method_missing(method, *args)
super(method, *args)
rescue NoMethodError
method_name = method.to_s

#setter method
if method_name =~ /=$/
self[method_name.chomp("=")] = args.first
#getter
else
self[method_name]
end
end

29eebabc Ohad Levy
def value= val
v = (val.nil? or val == default) ? nil : val.to_yaml
d9a2ebac Ohad Levy
self.class.cache.delete(name.to_s)
29eebabc Ohad Levy
write_attribute :value, v
end

76607ed5 Ohad Levy
def value
29eebabc Ohad Levy
v = read_attribute(:value)
v.nil? ? default : YAML.load(v)
76607ed5 Ohad Levy
end
29eebabc Ohad Levy
alias_method :value_before_type_cast, :value

def default
YAML.load(read_attribute(:default))
end

def default=(v)
write_attribute :default, v.to_yaml
end

alias_method :default_before_type_cast, :default
76607ed5 Ohad Levy
private

d9a2ebac Ohad Levy
def self.cache
Rails.cache
end

76607ed5 Ohad Levy
def save_as_settings_type
29eebabc Ohad Levy
return true unless settings_type.nil?
76607ed5 Ohad Levy
t = default.class.to_s.downcase
if TYPES.include?(t)
self.settings_type = t
else
self.settings_type = "integer" if default.is_a?(Integer)
self.settings_type = "boolean" if default.is_a?(TrueClass) or default.is_a?(FalseClass)
end
end

29eebabc Ohad Levy
def fix_types
case settings_type
when "boolean"
76607ed5 Ohad Levy
self.value = true if value == "true"
self.value = false if value == "false"
29eebabc Ohad Levy
when "integer"
self.value = value.to_i if value =~ /\d+/
df886c98 Ohad Levy
when "array"
if value =~ /^\s*\[.*\]\s*$/
begin
self.value = YAML.load(value.gsub(/(\,)(\S)/, "\\1 \\2"))
rescue => e
errors.add(:value, "invalid value: #{e}")
return false
end
else
errors.add(:value, "Must be an array")
return false
end
76607ed5 Ohad Levy
end
29eebabc Ohad Levy
true
76607ed5 Ohad Levy
end

def validate_attributes
return true if new_record?
changed_attributes.keys.each do |c|
if FROZEN_ATTRS.include?(c.to_s)
errors.add(c, "is not allowed to change")
return false
end
end
true
end
end