legacy_enum 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|