Class: EnumX
- Inherits:
-
Object
- Object
- EnumX
- Includes:
- Enumerable
- Defined in:
- lib/enum_x.rb,
lib/enum_x/dsl.rb,
lib/enum_x/value.rb,
lib/enum_x/railtie.rb,
lib/enum_x/version.rb,
lib/enum_x/value_list.rb
Overview
Utility class representing an enumeration of options to choose from. This can be used in models to make a field have a certain number of allowed options.
Enums are defined in configuration files which are loaded from load paths (see EnumX.load_paths).
EnumX file format
EnumX files are YAML files defining enumerations in the following format:
<name>: [ <value>, <value, ... ]
E.g.
statuses: [ draft, sent, returned ]
Extra formats
EnumX values are designed to be converted to various formats. By default, they simply support a name, which is the value you specify in the YAML files. They also respond to any method starting with ‘to_’, e.g. to_string
, to_json
, to_legacy
. These return the name of the value, unless otherwise specified explicitly when being defined.
If you want to provide extra formats in the YAML, you may indicate them as follows:
statuses: [ { value: 'draft', legacy: 'new' }, sent, { value: 'returned', legacy: 'back' } ]
Now, the following will all be true:
EnumX.statuses[:draft].value == 'draft'
EnumX.statuses[:draft].symbol == :draft
# => #symbol always returns the value converted to a Symbol
EnumX.statuses[:draft].to_legacy == 'new'
EnumX.statuses[:sent].value == 'sent'
EnumX.statuses[:sent].symbol == :sent
EnumX.statuses[:sent].to_legacy == 'sent'
# => because no explicit value for the 'legacy' format was specified
Defined Under Namespace
Modules: DSL Classes: Railtie, Registry, Value, ValueHash, ValueList
Constant Summary collapse
- VERSION =
'1.1.0'
Class Attribute Summary collapse
-
.loader ⇒ Object
Allows overriding of the load handler.
Instance Attribute Summary collapse
-
#name ⇒ String
readonly
The name of the enum.
-
#values ⇒ Array<EnumX::Value>
(also: #to_ary, #to_a)
readonly
All allowed enum values.
Class Method Summary collapse
-
.[](name) ⇒ Object
Retrieves an enum by name.
-
.define(name, values) ⇒ Object
Defines a new enum with the given values.
-
.find(klass, name) ⇒ Object
Finds an enum with the given name on a class.
- .load_paths ⇒ Object
-
.load_paths=(paths) ⇒ Object
An array of EnumX load paths.
-
.undefine(name) ⇒ Object
Undefines an enum.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Obtains a value by its key.
-
#dup ⇒ Object
Creates a duplicate of this enum.
-
#extend!(*values) ⇒ Object
Adds the given values to the enum.
-
#i18n_scope ⇒ Object
The I18n scope for this enum.
-
#initialize(name, values) ⇒ EnumX
constructor
Initializes a new EnumX instance.
-
#only(*values) ⇒ Object
Creates a duplicate of this enumeration but with only the given values.
-
#value_with_format(format, search) ⇒ Object
Finds an enum value by the given format.
-
#without(*values) ⇒ Object
Creates a clone of this enumeration but without the given values.
Constructor Details
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object (private)
314 315 316 317 318 319 320 321 |
# File 'lib/enum_x.rb', line 314 def method_missing(method, *args, &block) if method =~ /^value_with_(.*)$/ raise ArgumentError, "`#{method}' accepts one argument, #{args.length} given" unless args.length == 1 value_with_format $1, args.first else super end end |
Class Attribute Details
.loader ⇒ Object
Allows overriding of the load handler.
Specify an object that responds to load_enums_from(file, file_type) where file
is a file name, and file_type
is either :yaml
or :ruby
. Alternatively, a block may be specified that will receive these parameters.
The method does not have to return anything, but should use calls to define to actually define the enums.
By default, the loader parses the YAML file as a flat Hash, where the keys are enum names, and the values are arrays containing the values.
Usage
EnumX.loader = proc do |file, file_type|
if file_type == :ruby
load file
else
... # Process the YAML file here.
end
end
122 123 124 |
# File 'lib/enum_x.rb', line 122 def loader @loader end |
Instance Attribute Details
#name ⇒ String (readonly)
Returns The name of the enum.
205 206 207 |
# File 'lib/enum_x.rb', line 205 def name @name end |
#values ⇒ Array<EnumX::Value> (readonly) Also known as: to_ary, to_a
Returns All allowed enum values.
209 210 211 |
# File 'lib/enum_x.rb', line 209 def values @values.values end |
Class Method Details
.[](name) ⇒ Object
Retrieves an enum by name.
96 97 98 99 |
# File 'lib/enum_x.rb', line 96 def [](name) load_enums unless @registry registry[name] end |
.define(name, values) ⇒ Object
Defines a new enum with the given values.
86 87 88 |
# File 'lib/enum_x.rb', line 86 def define(name, values) registry[name.to_s] = new(name, values) end |
.find(klass, name) ⇒ Object
Finds an enum with the given name on a class. TODO: Spec
273 274 275 276 277 278 |
# File 'lib/enum_x.rb', line 273 def self.find(klass, name) return nil unless klass enum = klass.send(name) if klass.respond_to?(name) rescue nil enum if enum.is_a?(EnumX) end |
.load_paths ⇒ Object
80 81 82 |
# File 'lib/enum_x.rb', line 80 def load_paths @load_paths ||= [] end |
.load_paths=(paths) ⇒ Object
An array of EnumX load paths.
77 78 79 |
# File 'lib/enum_x.rb', line 77 def load_paths=(paths) @load_paths = Array.wrap(paths) end |
.undefine(name) ⇒ Object
Undefines an enum.
91 92 93 |
# File 'lib/enum_x.rb', line 91 def undefine(name) registry.delete name.to_s end |
Instance Method Details
#[](key) ⇒ Object
Obtains a value by its key.
226 227 228 |
# File 'lib/enum_x.rb', line 226 def [](key) @values[key] end |
#dup ⇒ Object
Creates a duplicate of this enum.
240 241 242 |
# File 'lib/enum_x.rb', line 240 def dup EnumX.new(name, values) end |
#extend!(*values) ⇒ Object
Adds the given values to the enum
255 256 257 |
# File 'lib/enum_x.rb', line 255 def extend!(*values) values.each { |value| add_value!(value) } end |
#i18n_scope ⇒ Object
The I18n scope for this enum. Override this to provide customization. Default: enums.<name>
264 265 266 |
# File 'lib/enum_x.rb', line 264 def i18n_scope [ :enums, name ] end |
#only(*values) ⇒ Object
Creates a duplicate of this enumeration but with only the given values.
250 251 252 |
# File 'lib/enum_x.rb', line 250 def only(*values) EnumX.new(name, self.values.select{|v| values.include?(v)}) end |
#value_with_format(format, search) ⇒ Object
Finds an enum value by the given format.
Example
Given the following enum:
@enum = EnumX.define(:my_enum,
{ :value => 'one', :number => '1' },
{ :value => 'two', :number => '2' }
)
You can now access the values like such:
@enum.value_with_format(:number, '1') # => @enum[:one]
@enum.value_with_format(:number, '2') # => @enum[:two]
Note that any undefined format for a value is defaulted to its value. Therefore, the following is also valid:
@enum.value_with_format(:unknown, 'one') # => @enum[:one]
You can also access values by a specific format using the shortcut ‘value_with_<format>’:
@enum.value_with_number('1') # => @enum[:one]
@enum.value_with_unknown('one') # => @enum[:one]
308 309 310 |
# File 'lib/enum_x.rb', line 308 def value_with_format(format, search) values.find { |val| val.send(:"to_#{format}") == search } end |