module Enumerate::Model
Public Instance Methods
enumerate(attribute, vals={}, opts={})
click to toggle source
# File lib/enumerate/model.rb, line 3 def enumerate(attribute, vals={}, opts={}) validates_inclusion_of attribute, :in => vals, :allow_nil => !!opts[:allow_nil] # Get the column type of the attribute. We support int and string if self.columns_hash[attribute.to_s].nil? raise "Column '#{attribute}' does not exist in #{self.class.name}" else col_type = self.columns_hash[attribute.to_s].type end const_hash_name = attribute.to_s.pluralize.upcase if col_type == :string vals = Hash[vals.zip vals.map{ |s| s.to_s }] if vals.kind_of?(Array) elsif col_type == :integer # Converts an array into a hash of values with indicies as the "values" vals = Hash[vals.zip (0...vals.size)] if vals.kind_of?(Array) else raise "Unsupported column type for enumeration :#{attribute} in #{self.class}!" end # Ensure that only arrays and hashes are appropriate datatypes. raise "Unsupported values datatype for enumeration :#{attribute} in #{self.class}!" if !vals.kind_of?(Hash) # Sets a class costant with the enumerated values const_set(const_hash_name, vals) setup_accessors(const_hash_name, attribute) setup_predicates(vals, attribute) end
Private Instance Methods
setup_accessors(const_hash_name, attribute)
click to toggle source
# File lib/enumerate/model.rb, line 40 def setup_accessors(const_hash_name, attribute) unless methods.include?(attribute.to_s) self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{attribute.to_s} #{const_hash_name}.key(read_attribute(:#{attribute})) end RUBY end unless methods.include?("#{attribute.to_s}=") self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{attribute.to_s}=(s) if (s.kind_of?(Fixnum)) write_attribute(:#{attribute}, s) elsif (s.kind_of?(Symbol) or s.kind_of?(String)) # puts "changing to \#{s}" write_attribute(:#{attribute}, #{const_hash_name}[s.to_sym]) # puts "is now \#{#{attribute}}" end end RUBY end end
setup_predicates(vals, attribute)
click to toggle source
# File lib/enumerate/model.rb, line 64 def setup_predicates(vals, attribute) vals.each do |key, val| raise "Collision in enumeration predicate method(s) #{key}" if respond_to?("#{key.to_s}?") or respond_to?("#{key.to_s}!") or respond_to?("not_#{key.to_s}?") or respond_to?("#{attribute.to_s}") define_method "#{key.to_s}?" do send("#{attribute.to_s}") == key end define_method "not_#{key.to_s}?" do send("#{attribute.to_s}") != key end define_method "#{key.to_s}!" do send("#{attribute.to_s}=", key) end # Define helper scopes self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 scope :#{key}, lambda { where(:#{attribute} => #{val}) } scope :not_#{key}, lambda { where("#{attribute} != #{val}") } RUBY end end