legacy_enum 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +151 -0
- data/lib/legacy_enum/class_methods.rb +37 -42
- data/lib/legacy_enum/configuration_search.rb +21 -0
- data/lib/legacy_enum/method_definition_dsl.rb +1 -0
- data/lib/legacy_enum/version.rb +1 -1
- data/lib/legacy_enum.rb +1 -0
- metadata +10 -9
- data/README.rdoc +0 -5
data/README.md
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# LegacyEnum
|
2
|
+
|
3
|
+
Allows your Rails app to interact with C-style integer-backed enumeration db columns using a more Ruby-ish syntax.
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
class Employee < ActiveRecord::Base
|
7
|
+
legacy_enum :payroll_type, lookup: :payroll_type_id do |e|
|
8
|
+
e.salaried 1
|
9
|
+
e.full_time 2
|
10
|
+
e.part_time 3
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# You can use a symbol syntax for more readable code.
|
15
|
+
employee = Employee.new
|
16
|
+
employee.payroll_type = :salaried
|
17
|
+
|
18
|
+
# The database still sees the column as an integer
|
19
|
+
p employee.payroll_type_id
|
20
|
+
# >> 1
|
21
|
+
|
22
|
+
# Labels are provided for humanized display of your enum values
|
23
|
+
p employee.payroll_type_label
|
24
|
+
# >> Salaried
|
25
|
+
|
26
|
+
# You can still address the column as a integer field (if you have to)
|
27
|
+
employee.payroll_type_id = 3
|
28
|
+
p employee.payroll_type
|
29
|
+
# >> :part_time
|
30
|
+
```
|
31
|
+
|
32
|
+
## Requires
|
33
|
+
|
34
|
+
* Rails >= 3.0
|
35
|
+
* Ruby >= 1.9.2
|
36
|
+
|
37
|
+
## Why?
|
38
|
+
|
39
|
+
Lots of legacy apps written in C/C++/C#/Java have integer columns in the database that represent enumerated values in the system.
|
40
|
+
|
41
|
+
For example, in a legacy system dealing with employees, an employee might be classified with a C-style enumeration like:
|
42
|
+
|
43
|
+
```c
|
44
|
+
enum PayrollType { Salaried = 1, FullTime, PartTime }
|
45
|
+
// stored in a db column named "PayrollTypeID" as its integer value
|
46
|
+
```
|
47
|
+
|
48
|
+
This could be accessed using legacy_enum like so:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
legacy_enum :payroll_type do |e|
|
52
|
+
e.salaried 1
|
53
|
+
e.full_time 2
|
54
|
+
e.part_time 3
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
legacy_enum [rails_friendly_name], options do |e|
|
62
|
+
e.enumerated_name value, [options]
|
63
|
+
...
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
## Options
|
68
|
+
|
69
|
+
#### Lookups
|
70
|
+
|
71
|
+
Conventionally, legacy_enum assumes that the backing int column is named the same as your field name, capitalized and postfixed with "ID". If that isn't the case, use the "lookup" option.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
legacy_enum :payroll_type, lookup: :unconventional_id_column_name do |e|
|
75
|
+
...
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
#### Values
|
80
|
+
|
81
|
+
Legacy_enum requires that a backing value be provided for each enumerated name. A value can be an integer or a string.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
legacy_enum :int_values do |e|
|
85
|
+
e.some_value 32
|
86
|
+
e.another_value 64
|
87
|
+
end
|
88
|
+
|
89
|
+
legacy_enum :string_values do |e|
|
90
|
+
e.a_string_value_is_ok 'zip_zop_zoobity_bop'
|
91
|
+
e.another_string 'here_i_go_down_the_slope'
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
#### Labels
|
96
|
+
|
97
|
+
Labels are automatically created and conventionally have the name [legacy_enum_field]_label. For instance, this definition would have a label named 'foo_label'
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
legacy_enum :foo do |e|
|
101
|
+
e.some_value 1
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Each enumerated name, by default, has a label that is just the ActiveSupport#Titleized version of the enum name. This can be overridden using the 'label' option for each value.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
legacy_enum :foo do |e|
|
109
|
+
e.crazy_label 1, label: 'Roflcopter'
|
110
|
+
end
|
111
|
+
|
112
|
+
foo = :crazy_label
|
113
|
+
p foo_label
|
114
|
+
# >> 'Roflcopter'
|
115
|
+
```
|
116
|
+
|
117
|
+
#### Scopes
|
118
|
+
|
119
|
+
ActiveRecord scopes can be created for your enumerated field, although by default they are not. The 'scope' option supports two values, :many and :one. 'Many' creates a scope with the enumeration name that accepts symbol values for the scope.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class Employee < ActiveRecord::Base
|
123
|
+
legacy_enum :payroll_type, lookup: :payroll_type_id, scope: :many do |e|
|
124
|
+
e.salaried 1
|
125
|
+
e.full_time 2
|
126
|
+
e.part_time 3
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# The following scopes are created
|
131
|
+
Employee.payroll_type(:salaried)
|
132
|
+
# 'SELECT * FROM employees WHERE payroll_type_id = 1'
|
133
|
+
Employee.salaried
|
134
|
+
# 'SELECT * FROM employees WHERE payroll_type_id = 1'
|
135
|
+
Employee.full_time
|
136
|
+
# 'SELECT * FROM employees WHERE payroll_type_id = 2'
|
137
|
+
Employee.part_time
|
138
|
+
# 'SELECT * FROM employees WHERE payroll_type_id = 3'
|
139
|
+
```
|
140
|
+
|
141
|
+
## Who?
|
142
|
+
|
143
|
+
legacy_enum was written by [Sean Scally](http://github.com/anydiem) for [AutoRevo](http://www.autorevo.com) with code contributed by [Matt Shannon](http://github.com/dmshann0n).
|
144
|
+
|
145
|
+
legacy_enum was inspired by jeffp's [enumerated_attribute](http://github.com/jeffp/enumerated_attribute).
|
146
|
+
|
147
|
+
## License
|
148
|
+
|
149
|
+
Released under the MIT license:
|
150
|
+
|
151
|
+
* http://www.opensource.org/licenses/MIT
|
@@ -1,84 +1,79 @@
|
|
1
1
|
module LegacyEnum
|
2
2
|
module ClassMethods
|
3
3
|
def legacy_enum(name, *options, &block)
|
4
|
-
|
5
|
-
|
6
|
-
id_attr_name = options[:lookup].try(:to_s) || "#{name.to_s.capitalize}ID"
|
4
|
+
extracted_options = options.extract_options!
|
5
|
+
id_attr_name = extracted_options[:lookup].try(:to_s) || "#{name.to_s.capitalize}ID"
|
7
6
|
|
8
7
|
config = MethodDefinitionDSL.new
|
9
8
|
config.instance_eval(&block)
|
10
9
|
|
11
10
|
cattr_accessor :enum_config unless defined? self.enum_config
|
12
11
|
self.enum_config ||= {}
|
13
|
-
self.enum_config[name] = config.enum_def
|
14
12
|
|
15
|
-
|
13
|
+
self.enum_config[name] = { values: config.enum_def, lookup: id_attr_name }
|
14
|
+
|
16
15
|
class_eval do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
21
|
-
self.enums[name].keys.each do |value|
|
22
|
-
if options[:scope] == :one
|
23
|
-
(class << self; self; end).instance_eval do
|
24
|
-
define_method value.to_sym, lambda {
|
25
|
-
send(name.to_sym, value.to_sym).first
|
26
|
-
}
|
27
|
-
end
|
28
|
-
else
|
29
|
-
(class << self; self; end).instance_eval do
|
30
|
-
define_method value.to_sym, lambda {
|
31
|
-
send(name.to_sym, value.to_sym)
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
16
|
+
|
17
|
+
define_method name do
|
18
|
+
enum_config[name][:values].valued(legacy_value(name))[:name]
|
36
19
|
end
|
37
20
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
21
|
+
define_method "#{name}=" do |value|
|
22
|
+
set_value = enum_config[name][:values].named(value)[:value]
|
23
|
+
set_legacy_value name, set_value
|
24
|
+
end
|
43
25
|
|
44
|
-
|
26
|
+
define_method "#{name}_label" do
|
27
|
+
enum_config[name][:values].valued(legacy_value(name))[:label]
|
45
28
|
end
|
46
29
|
|
47
|
-
|
48
|
-
|
30
|
+
def legacy_value(name)
|
31
|
+
send enum_config[name][:lookup].to_sym
|
49
32
|
end
|
50
33
|
|
51
|
-
|
52
|
-
|
53
|
-
enum_entry = self.enum_config[name].find { |hash| hash[:name] == (value.blank? ? value : value.to_sym) }
|
54
|
-
unless enum_entry.blank?
|
55
|
-
self.send("#{id_attr_name}=".to_sym, enum_entry[:value])
|
56
|
-
end
|
34
|
+
def set_legacy_value(name, value)
|
35
|
+
send "#{enum_config[name][:lookup]}=".to_sym, value
|
57
36
|
end
|
58
37
|
|
59
|
-
|
60
|
-
|
38
|
+
return unless extracted_options[:scope]
|
39
|
+
|
40
|
+
scope name.to_sym,
|
41
|
+
lambda { |enum_value| where(id_attr_name => enum_config[name][:values].named(enum_value)[:value] ) }
|
42
|
+
|
43
|
+
enum_config[name][:values].each do |config|
|
44
|
+
singleton_class.instance_eval do
|
45
|
+
if extracted_options[:scope] == :one
|
46
|
+
define_method config[:name].to_sym, lambda { send(name, config[:name]).first }
|
47
|
+
else
|
48
|
+
define_method config[:name].to_sym, lambda { send(name, config[:name]) }
|
49
|
+
end
|
50
|
+
end
|
61
51
|
end
|
52
|
+
|
62
53
|
end
|
54
|
+
|
63
55
|
end
|
64
56
|
|
57
|
+
# Returns all enumerations for the class by enum_name and then name => value
|
65
58
|
def enums
|
66
59
|
inject_block(:name, :value)
|
67
60
|
end
|
68
61
|
|
62
|
+
# Returns all enumerations for the class by enum_name and then name => label
|
69
63
|
def labels
|
70
64
|
inject_block(:name, :label)
|
71
65
|
end
|
72
66
|
|
67
|
+
# Returns all enumerations for the class by enum_name and then value => name
|
73
68
|
def enum_ids
|
74
69
|
inject_block(:value, :name)
|
75
70
|
end
|
76
71
|
|
77
72
|
private
|
78
|
-
#
|
73
|
+
# Restructures the enum_config around a key/value pair
|
79
74
|
def inject_block(key, value)
|
80
75
|
self.enum_config.inject({}) do |acc, (name,config)|
|
81
|
-
acc.merge( { name => config.inject({}) do |inner_acc, enum_item|
|
76
|
+
acc.merge( { name => config[:values].inject({}) do |inner_acc, enum_item|
|
82
77
|
inner_acc.merge( { enum_item[key] => enum_item[value] } )
|
83
78
|
end })
|
84
79
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LegacyEnum
|
2
|
+
module ConfigurationSearch
|
3
|
+
def named(name)
|
4
|
+
find { |config| config[:name] == name } || null_definition
|
5
|
+
end
|
6
|
+
|
7
|
+
def valued(value)
|
8
|
+
search_value = value.to_s.upcase
|
9
|
+
find { |config| config[:value].to_s.upcase === search_value } || null_definition
|
10
|
+
end
|
11
|
+
|
12
|
+
def labelled(label)
|
13
|
+
find { |config| config[:label] == label } || null_definition
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def null_definition
|
18
|
+
{ name: nil, value: nil, label: nil }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/legacy_enum/version.rb
CHANGED
data/lib/legacy_enum.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: legacy_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &70249318379200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>'
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70249318379200
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sqlite3
|
27
|
-
requirement: &
|
27
|
+
requirement: &70249318378160 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70249318378160
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70249318376680 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70249318376680
|
47
47
|
description: Allows you to address enumerated integer columns as more sane and readable
|
48
48
|
symbols
|
49
49
|
email:
|
@@ -53,13 +53,14 @@ extensions: []
|
|
53
53
|
extra_rdoc_files: []
|
54
54
|
files:
|
55
55
|
- lib/legacy_enum/class_methods.rb
|
56
|
+
- lib/legacy_enum/configuration_search.rb
|
56
57
|
- lib/legacy_enum/method_definition_dsl.rb
|
57
58
|
- lib/legacy_enum/version.rb
|
58
59
|
- lib/legacy_enum.rb
|
59
60
|
- lib/tasks/legacy_enum_tasks.rake
|
60
61
|
- MIT-LICENSE
|
61
62
|
- Rakefile
|
62
|
-
- README.
|
63
|
+
- README.md
|
63
64
|
homepage: http://github.com/anydiem/legacy_enum
|
64
65
|
licenses: []
|
65
66
|
post_install_message:
|