enumerate_it 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/enumerate_it.gemspec +2 -2
- data/lib/enumerate_it.rb +53 -56
- data/spec/enumerate_it_spec.rb +22 -8
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.2
|
data/enumerate_it.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{enumerate_it}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["C\303\241ssio Marques"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-01-24}
|
13
13
|
s.description = %q{Have a legacy database and need some enumerations in your models to match those stupid '4 rows/2 columns' tables with foreign keys and stop doing joins just to fetch a simple description? Or maybe use some integers instead of strings as the code for each value of your enumerations? Here's EnumerateIt.}
|
14
14
|
s.email = %q{cassiommc@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/enumerate_it.rb
CHANGED
@@ -8,27 +8,27 @@
|
|
8
8
|
#
|
9
9
|
# Ok, I know there are a lot of different solutions to this problem. But none of them solved my problem,
|
10
10
|
# so here's EnumerateIt. I needed to build a Rails application around a legacy database and this database was
|
11
|
-
# filled with those small, unchangeable tables used to create foreign key constraints everywhere.
|
11
|
+
# filled with those small, unchangeable tables used to create foreign key constraints everywhere.
|
12
12
|
#
|
13
13
|
# == For example:
|
14
14
|
#
|
15
15
|
# Table "public.relationshipstatus"
|
16
|
-
# Column | Type | Modifiers
|
16
|
+
# Column | Type | Modifiers
|
17
17
|
# -------------+---------------+-----------
|
18
18
|
# code | character(1) | not null
|
19
|
-
# description | character(11) |
|
19
|
+
# description | character(11) |
|
20
20
|
# Indexes:
|
21
21
|
# "relationshipstatus_pkey" PRIMARY KEY, btree (code)
|
22
22
|
#
|
23
23
|
# select * from relationshipstatus;
|
24
|
-
# code | description
|
24
|
+
# code | description
|
25
25
|
# --------+--------------
|
26
|
-
# 1 | Single
|
27
|
-
# 2 | Married
|
26
|
+
# 1 | Single
|
27
|
+
# 2 | Married
|
28
28
|
# 3 | Widow
|
29
|
-
# 4 | Divorced
|
30
|
-
#
|
31
|
-
# And then I had things like a people table with a 'relationship_status' column with a foreign key
|
29
|
+
# 4 | Divorced
|
30
|
+
#
|
31
|
+
# And then I had things like a people table with a 'relationship_status' column with a foreign key
|
32
32
|
# pointing to the relationshipstatus table.
|
33
33
|
#
|
34
34
|
# While this is a good thing from the database normalization perspective, managing this values in
|
@@ -39,8 +39,8 @@
|
|
39
39
|
#
|
40
40
|
# = Creating enumerations
|
41
41
|
#
|
42
|
-
# Enumerations are created as models, but you can put then anywhere in your application. In Rails
|
43
|
-
# applications, I put them inside models/.
|
42
|
+
# Enumerations are created as models, but you can put then anywhere in your application. In Rails
|
43
|
+
# applications, I put them inside models/.
|
44
44
|
#
|
45
45
|
# class RelationshipStatus < EnumerateIt::Base
|
46
46
|
# associate_values(
|
@@ -87,9 +87,9 @@
|
|
87
87
|
# end
|
88
88
|
#
|
89
89
|
# The :with option is not required. If you ommit it, EnumerateIt will try to load an
|
90
|
-
# enumeration class based on the camelized attribute name.
|
90
|
+
# enumeration class based on the camelized attribute name.
|
91
91
|
#
|
92
|
-
# This will create:
|
92
|
+
# This will create:
|
93
93
|
#
|
94
94
|
# - A humanized description for the values of the enumerated attribute:
|
95
95
|
#
|
@@ -97,14 +97,14 @@
|
|
97
97
|
# p.relationship_status = RelationshipStatus::DIVORCED
|
98
98
|
# p.relationship_status_humanize # => 'Divorced'
|
99
99
|
#
|
100
|
-
# - If you don't supply a humanized string to represent an option, EnumerateIt will use a 'humanized'
|
100
|
+
# - If you don't supply a humanized string to represent an option, EnumerateIt will use a 'humanized'
|
101
101
|
# version of the hash's key to humanize the attribute's value
|
102
102
|
#
|
103
103
|
# class RelationshipStatus < EnumerateIt::Base
|
104
104
|
# associate_values(
|
105
105
|
# :married => 1,
|
106
106
|
# :single => 2
|
107
|
-
# )
|
107
|
+
# )
|
108
108
|
# end
|
109
109
|
#
|
110
110
|
# p = Person.new
|
@@ -141,29 +141,29 @@
|
|
141
141
|
# has_enumeration_for :relationship_status, :required => true # => defaults to false
|
142
142
|
# end
|
143
143
|
#
|
144
|
-
# Remember that in Rails 3 you can add validations to any kind of class and not only to those derived from
|
144
|
+
# Remember that in Rails 3 you can add validations to any kind of class and not only to those derived from
|
145
145
|
# ActiveRecord::Base.
|
146
146
|
#
|
147
147
|
# = Using with Rails/ActiveRecord
|
148
|
-
#
|
148
|
+
#
|
149
149
|
# * Create an initializer with the following code:
|
150
|
-
#
|
150
|
+
#
|
151
151
|
# ActiveRecord::Base.send :include, EnumerateIt
|
152
|
-
#
|
152
|
+
#
|
153
153
|
# * Add the 'enumerate_it' gem as a dependency in your environment.rb (Rails 2.3.x) or Gemfile (if you're using Bundler)
|
154
154
|
#
|
155
155
|
# = Why did you reinvent the wheel?
|
156
156
|
#
|
157
157
|
# There are other similar solutions to the problem out there, but I could not find one that
|
158
|
-
# worked both with strings and integers as the enumerations' codes. I had both situations in
|
159
|
-
# my legacy database.
|
158
|
+
# worked both with strings and integers as the enumerations' codes. I had both situations in
|
159
|
+
# my legacy database.
|
160
160
|
#
|
161
161
|
# = Why defining enumerations outside the class that used it?
|
162
162
|
#
|
163
163
|
# - I think it's cleaner.
|
164
164
|
# - You can add behaviour to the enumeration class.
|
165
165
|
# - You can reuse the enumeration inside other classes.
|
166
|
-
#
|
166
|
+
#
|
167
167
|
module EnumerateIt
|
168
168
|
class Base
|
169
169
|
@@registered_enumerations = {}
|
@@ -171,12 +171,38 @@ module EnumerateIt
|
|
171
171
|
def self.associate_values(values_hash)
|
172
172
|
register_enumeration normalize_enumeration(values_hash)
|
173
173
|
values_hash.each_pair { |value_name, attributes| define_enumeration_constant value_name, attributes[0] }
|
174
|
-
|
175
|
-
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.list
|
177
|
+
enumeration.values.map { |value| value[0] }.sort
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.enumeration
|
181
|
+
@@registered_enumerations[self]
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.to_a
|
185
|
+
enumeration.values.map {|value| [translate(value[1]), value[0]] }.sort_by { |value| value[0] }
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.values_for(values)
|
189
|
+
values.map { |v| self.const_get(v.to_sym) }
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.to_range
|
193
|
+
(list.min..list.max)
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.translate(value)
|
197
|
+
return value unless value.is_a? Symbol
|
198
|
+
|
199
|
+
default = value.to_s.to_s.gsub(/_/, ' ').split.map(&:capitalize).join(' ')
|
200
|
+
I18n.t("enumerations.#{self.name.underscore}.#{value.to_s.underscore}", :default => default)
|
201
|
+
end
|
176
202
|
|
177
203
|
private
|
178
204
|
def self.normalize_enumeration(values_hash)
|
179
|
-
values_hash.each_pair do |key, value|
|
205
|
+
values_hash.each_pair do |key, value|
|
180
206
|
unless value.is_a? Array
|
181
207
|
values_hash[key] = [value, key]
|
182
208
|
end
|
@@ -191,35 +217,6 @@ module EnumerateIt
|
|
191
217
|
def self.define_enumeration_constant(name, value)
|
192
218
|
const_set name.to_s.upcase, value
|
193
219
|
end
|
194
|
-
|
195
|
-
def self.define_enumeration_list(values_hash)
|
196
|
-
def self.list
|
197
|
-
@@registered_enumerations[self].values.map { |value| translate(value[0]) }.sort
|
198
|
-
end
|
199
|
-
|
200
|
-
def self.enumeration
|
201
|
-
@@registered_enumerations[self]
|
202
|
-
end
|
203
|
-
|
204
|
-
def self.to_a
|
205
|
-
@@registered_enumerations[self].values.map {|value| [translate(value[1]), value[0]] }.sort_by { |value| value[0] }
|
206
|
-
end
|
207
|
-
|
208
|
-
def self.to_range
|
209
|
-
(list.min..list.max)
|
210
|
-
end
|
211
|
-
|
212
|
-
def self.values_for(values)
|
213
|
-
values.map { |v| self.const_get(v.to_sym) }
|
214
|
-
end
|
215
|
-
|
216
|
-
def self.translate(value)
|
217
|
-
return value unless value.is_a? Symbol
|
218
|
-
|
219
|
-
default = value.to_s.to_s.gsub(/_/, ' ').split.map(&:capitalize).join(' ')
|
220
|
-
I18n.t("enumerations.#{self.name.underscore}.#{value.to_s.underscore}", :default => default)
|
221
|
-
end
|
222
|
-
end
|
223
220
|
end
|
224
221
|
|
225
222
|
module ClassMethods
|
@@ -238,11 +235,11 @@ module EnumerateIt
|
|
238
235
|
class_eval do
|
239
236
|
define_method "#{attribute_name}_humanize" do
|
240
237
|
values = klass.enumeration.values.detect { |v| v[0] == self.send(attribute_name) }
|
241
|
-
|
238
|
+
|
242
239
|
values ? klass.translate(values[1]) : nil
|
243
240
|
end
|
244
241
|
end
|
245
|
-
end
|
242
|
+
end
|
246
243
|
|
247
244
|
def create_helper_methods(klass, attribute_name)
|
248
245
|
class_eval do
|
data/spec/enumerate_it_spec.rb
CHANGED
@@ -16,6 +16,16 @@ class TestEnumerationWithoutArray < EnumerateIt::Base
|
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
19
|
+
class TestEnumerationWithExtendedBehaviour < EnumerateIt::Base
|
20
|
+
associate_values(
|
21
|
+
:first => '1',
|
22
|
+
:second => '2'
|
23
|
+
)
|
24
|
+
def self.to_a
|
25
|
+
super.reverse
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
19
29
|
describe EnumerateIt do
|
20
30
|
before :each do
|
21
31
|
class TestClass
|
@@ -26,7 +36,7 @@ describe EnumerateIt do
|
|
26
36
|
def initialize(foobar); @foobar = foobar; end
|
27
37
|
I18n.locale = :en
|
28
38
|
end
|
29
|
-
|
39
|
+
|
30
40
|
@target = TestClass.new(TestEnumeration::VALUE_2)
|
31
41
|
end
|
32
42
|
|
@@ -51,24 +61,24 @@ describe EnumerateIt do
|
|
51
61
|
attr_accessor :foobar
|
52
62
|
has_enumeration_for :foobar, :with => TestEnumerationWithoutArray
|
53
63
|
|
54
|
-
def initialize(foobar); @foobar = foobar; end
|
64
|
+
def initialize(foobar); @foobar = foobar; end
|
55
65
|
end
|
56
66
|
|
57
67
|
@target = TestClassForEnumerationWithoutArray.new(TestEnumerationWithoutArray::VALUE_TWO)
|
58
68
|
end
|
59
|
-
|
69
|
+
|
60
70
|
it "humanizes the respective hash key" do
|
61
71
|
@target.foobar_humanize.should == 'Value Two'
|
62
72
|
end
|
63
|
-
|
73
|
+
|
64
74
|
it "translates the respective hash key when a translation is found" do
|
65
75
|
@target.foobar = TestEnumerationWithoutArray::VALUE_ONE
|
66
76
|
@target.foobar_humanize.should == 'First Value'
|
67
77
|
I18n.locale = :pt
|
68
|
-
|
78
|
+
|
69
79
|
@target.foobar_humanize.should == 'Primeiro Valor'
|
70
80
|
end
|
71
|
-
|
81
|
+
|
72
82
|
end
|
73
83
|
|
74
84
|
context "without passing the enumeration class" do
|
@@ -139,12 +149,16 @@ describe EnumerateIt do
|
|
139
149
|
it "returns an array with the values and human representations" do
|
140
150
|
TestEnumeration.to_a.should == [['Hey, I am 1!', '1'], ['Hey, I am 2!', '2'], ['Hey, I am 3!', '3']]
|
141
151
|
end
|
142
|
-
|
152
|
+
|
143
153
|
it "translates the available values" do
|
144
154
|
TestEnumerationWithoutArray.to_a.should == [['First Value', '1'], ['Value Two', '2']]
|
145
155
|
I18n.locale = :pt
|
146
156
|
TestEnumerationWithoutArray.to_a.should == [['Primeiro Valor', '1'], ['Value Two', '2']]
|
147
157
|
end
|
158
|
+
|
159
|
+
it "can be extended from the enumeration class" do
|
160
|
+
TestEnumerationWithExtendedBehaviour.to_a.should == [['Second', '2'],['First','1']]
|
161
|
+
end
|
148
162
|
end
|
149
163
|
|
150
164
|
describe "#to_range" do
|
@@ -169,7 +183,7 @@ describe EnumerateIt do
|
|
169
183
|
def validates_presence_of; true; end
|
170
184
|
end
|
171
185
|
end
|
172
|
-
|
186
|
+
|
173
187
|
ActiveRecordStub.stub!(:validates_inclusion_of).and_return(true)
|
174
188
|
ActiveRecordStub.send :include, EnumerateIt
|
175
189
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerate_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 2
|
10
|
+
version: 0.7.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "C\xC3\xA1ssio Marques"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-24 00:00:00 -02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|