module RailsAttrEnum
Constants
- Entry
Enum
entry class- EntryValue
Forwarding class for actual attribute value
- VERSION
Public Instance Methods
attr_enum(attr_name, *keys, &block)
click to toggle source
# File lib/rails_attr_enum.rb, line 10 def attr_enum(attr_name, *keys, &block) if block_given? add_attr_enum_through_block(attr_name, &block) else if keys.first.is_a?(Hash) && keys.first.size > 1 add_attr_enum_through_block(attr_name) do keys.first.each { |k, v| add k => v } end else add_attr_enum_through_block(attr_name) do keys.each { |k| add k } end end end nil end
Private Instance Methods
add_attr_enum(attr_name, entries, validation_rules)
click to toggle source
# File lib/rails_attr_enum.rb, line 30 def add_attr_enum(attr_name, entries, validation_rules) attr = Attr.new(attr_name) @_attr_enums ||= {} if table_exists? && !column_names.include?(attr.name) puts "Warning: Cannot create enum for '#{attr.name}' because that attribute does not exist for '#{self.name}'" return end if @_attr_enums.any? { |(_, enm)| enm.attr_name == attr.name } raise "Already defined enum for '#{attr.name}'" end @_attr_enums[attr.name.to_sym] = Module.new { include Enum }.tap do |mod| mod.init_enum(attr.name) const_set(attr.enum_name, mod) entries.each do |entry| mod.add(entry) class_eval <<-EOS scope :#{attr.name}_#{entry.key}, -> { where(:#{attr.name} => #{entry.value}) } EOS end validates(attr.name.to_sym, validation_rules.merge(inclusion: { in: mod.values })) end add_methods(attr) end
add_attr_enum_through_block(attr_name, &block)
click to toggle source
# File lib/rails_attr_enum.rb, line 61 def add_attr_enum_through_block(attr_name, &block) acc = EnumAccumulator.new acc.instance_eval(&block) add_attr_enum(attr_name, acc.entries, acc.validation_rules) end
add_methods(attr)
click to toggle source
def add_attr_display_method(attr)
# File lib/rails_attr_enum.rb, line 68 def add_methods(attr) class_eval <<-EOS, __FILE__, __LINE__ + 1 # Add the display method like 'display_status' for attribute 'status' def display_#{attr.name} value = read_attribute(:#{attr.name}) return '' if value.nil? self.class.instance_variable_get(:@_attr_enums)[:#{attr.name}].get_label(value) end # Add method like 'status?' for attribute 'status' def #{attr.name}?(key = nil) if key.nil? !read_attribute(:#{attr.name}).nil? else read_attribute(:#{attr.name}) == #{attr.enum_name}.const_get(key.to_s.upcase) end end # Override the attr= method def #{attr.name}=(key) if key.is_a? Symbol #{attr.enum_name}.const_get(key.to_s.upcase).tap do |value| write_attribute(:#{attr.name}, value) end else super end end # Override the attr method def #{attr.name} EntryValue.new(self, :#{attr.name}, #{attr.enum_name}) end EOS end