Module: ActiveRecord::VirtualEnumerations
- Defined in:
- lib/active_record/virtual_enumerations.rb
Overview
Implements a mechanism to synthesize enum classes for simple enums. This is for situations where you wish to avoid cluttering the models directory with your enums.
Create a custom Rails initializer: Rails.root/config/initializers/virtual_enumerations.rb
ActiveRecord::VirtualEnumerations.define do |config|
config.define 'ClassName',
:table_name => 'table',
:extends => 'SuperclassName',
:conditions => ['something = ?', "value"],
:order => 'column ASC',
:on_lookup_failure => :enforce_strict,
:name_column => 'name_column',
:alias_name => false {
# class_evaled_functions
}
end
Only the 'ClassName' argument is required. :table_name is used to define a custom table name while the :extends option is used to set a custom superclass. Class names can be either camel-cased like ClassName or with underscores, like class_name. Strings and symbols are both fine.
If you need to fine-tune the definition of the enum class, you can optionally pass in a block, which will be evaluated in the context of the enum class.
Example:
config.define :color, :on_lookup_failure => :enforce_strict, do
def to_argb(alpha)
case self.to_sym
when :white
[alpha, 255, 255, 255]
when :red
[alpha, 255, 0, 0]
when :blue
[alpha, 0, 0, 255]
when :yellow
[alpha, 255, 255, 0]
when :black
[alpha, 0, 0, 0]
end
end
end
As a convenience, if multiple enums share the same configuration, you can pass all of them to config.define.
Example:
config.define :booking_status, :connector_type, :color, :order => :name
Single Table Inheritance is also supported:
Example:
config.define :base_enum, :name_column => ;foo
config.define :booking_status, :connector_type, :color, :extends => :base_enum
Defined Under Namespace
Classes: Config
Class Method Summary collapse
-
.define {|config| ... } ⇒ Object
Defines enumeration classes.
-
.patch_const_lookup ⇒ Object
Patches Module#const_missing to enable us to dynamically create enum classes at runtime.
-
.synthesize_if_defined(const) ⇒ Object
Creates a constant for a virtual enum if a config is defined for it.
Class Method Details
.define {|config| ... } ⇒ Object
Defines enumeration classes. Passes a config object to the given block which is used to define the virtual enumerations. Call config.define for each enum or enums with a given set of options.
94 95 96 97 98 99 100 |
# File 'lib/active_record/virtual_enumerations.rb', line 94 def self.define raise ArgumentError, "#{self.name}: must pass a block to define()" unless block_given? patch_const_lookup config = ActiveRecord::VirtualEnumerations::Config.new yield config @config = config # we only overwrite config if no exceptions were thrown end |
.patch_const_lookup ⇒ Object
Patches Module#const_missing to enable us to dynamically create enum classes at runtime.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/active_record/virtual_enumerations.rb', line 69 def self.patch_const_lookup # Make sure we haven't patched Module already unless ::Module.respond_to?(:enumerations_original_const_missing) # patch Module to support VirtualEnumerations ::Module.module_eval do alias_method :enumerations_original_const_missing, :const_missing # Override const_missing to see if VirtualEnumerations can create it. def const_missing(const_id) # let rails have a go at loading it enumerations_original_const_missing(const_id) rescue NameError # now it's our turn ActiveRecord::VirtualEnumerations.synthesize_if_defined(const_id) or raise end end end end |
.synthesize_if_defined(const) ⇒ Object
Creates a constant for a virtual enum if a config is defined for it.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/active_record/virtual_enumerations.rb', line 103 def self.synthesize_if_defined(const) if @config && = @config[const] class_declaration = "class #{const} < #{[:extends]}; end" eval( class_declaration, TOPLEVEL_BINDING, __FILE__, __LINE__ ) virtual_enum_class = const_get( const ) ( virtual_enum_class, ) virtual_enum_class else nil end end |