simple_enum 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +9 -0
- data/lib/simple_enum/version.rb +1 -1
- data/lib/simple_enum.rb +22 -2
- data/test/class_methods_test.rb +28 -23
- data/test/dirty_attributes_test.rb +38 -0
- data/test/simple_enum_test.rb +16 -0
- metadata +5 -3
data/README.rdoc
CHANGED
@@ -162,6 +162,15 @@ useful when creating queries, displaying option elements or similar:
|
|
162
162
|
|
163
163
|
== Best practices
|
164
164
|
|
165
|
+
Do not use the same name for the enum as for the column, note that this mode of use is
|
166
|
+
deprecated starting with version 1.4.1, e.g.
|
167
|
+
|
168
|
+
# BAD
|
169
|
+
as_enum :status, [:active, :inactive, :archived], :column => "status"
|
170
|
+
|
171
|
+
# GOOD
|
172
|
+
as_enum :project_status, [:active, :inactive, :archived], :column => "status"
|
173
|
+
|
165
174
|
Searching for certain values by using the finder methods:
|
166
175
|
|
167
176
|
User.where(:gender_cd => User.female)
|
data/lib/simple_enum/version.rb
CHANGED
data/lib/simple_enum.rb
CHANGED
@@ -15,6 +15,8 @@ require 'simple_enum/enum_hash'
|
|
15
15
|
require 'simple_enum/object_support'
|
16
16
|
require 'simple_enum/validation'
|
17
17
|
|
18
|
+
require 'active_support/deprecation'
|
19
|
+
|
18
20
|
# Base module which gets included in <tt>ActiveRecord::Base</tt>. See documentation
|
19
21
|
# of +SimpleEnum::ClassMethods+ for more details.
|
20
22
|
module SimpleEnum
|
@@ -33,6 +35,8 @@ module SimpleEnum
|
|
33
35
|
# * <tt>:whiny</tt> - Boolean value which if set to <tt>true</tt> will throw an <tt>ArgumentError</tt>
|
34
36
|
# if an invalid value is passed to the setter (e.g. a value for which no enumeration exists). if set to
|
35
37
|
# <tt>false</tt> no exception is thrown and the internal value is set to <tt>nil</tt> (default is <tt>true</tt>)
|
38
|
+
# * <tt>:dirty</tt> - Boolean value which if set to <tt>true</tt> generates <tt>..._was</tt> and <tt>..._changed?</tt>
|
39
|
+
# methods for the enum, which delegate to the internal column.
|
36
40
|
def default_options
|
37
41
|
@default_options ||= {
|
38
42
|
:whiny => true,
|
@@ -67,7 +71,7 @@ module SimpleEnum
|
|
67
71
|
# # or use a hash:
|
68
72
|
#
|
69
73
|
# class User < ActiveRecord::Base
|
70
|
-
# as_enum :
|
74
|
+
# as_enum :user_status, { :active => 1, :inactive => 0, :archived => 2, :deleted => 3 }, :column => 'status'
|
71
75
|
# end
|
72
76
|
#
|
73
77
|
# Now it's possible to access the enumeration and the internally stored value like:
|
@@ -149,9 +153,11 @@ module SimpleEnum
|
|
149
153
|
# * <tt>:whiny</tt> - Boolean value which if set to <tt>true</tt> will throw an <tt>ArgumentError</tt>
|
150
154
|
# if an invalid value is passed to the setter (e.g. a value for which no enumeration exists). if set to
|
151
155
|
# <tt>false</tt> no exception is thrown and the internal value is set to <tt>nil</tt> (default is <tt>true</tt>)
|
156
|
+
# * <tt>:dirty</tt> - Boolean value which if set to <tt>true</tt> generates <tt>..._was</tt> and <tt>..._changed?</tt>
|
157
|
+
# methods for the enum, which delegate to the internal column (default is <tt>false</tt>)
|
152
158
|
def as_enum(enum_cd, values, options = {})
|
153
159
|
options = SimpleEnum.default_options.merge({ :column => "#{enum_cd}_cd" }).merge(options)
|
154
|
-
options.assert_valid_keys(:column, :whiny, :prefix, :slim, :upcase)
|
160
|
+
options.assert_valid_keys(:column, :whiny, :prefix, :slim, :upcase, :dirty)
|
155
161
|
|
156
162
|
metaclass = (class << self; self; end)
|
157
163
|
|
@@ -163,6 +169,9 @@ module SimpleEnum
|
|
163
169
|
self.enum_definitions = {} if self.enum_definitions.nil?
|
164
170
|
self.enum_definitions[enum_cd] = self.enum_definitions[options[:column]] = { :name => enum_cd, :column => options[:column], :options => options }
|
165
171
|
|
172
|
+
# display deprecation warning if enum_cd == column
|
173
|
+
ActiveSupport::Deprecation.warn "[simple_enum] use different names for #{enum_cd}'s name and column name (support for this will be dropped in 1.5)" if enum_cd.to_s == options[:column].to_s
|
174
|
+
|
166
175
|
# generate getter
|
167
176
|
define_method("#{enum_cd}") do
|
168
177
|
id = read_attribute options[:column]
|
@@ -176,6 +185,17 @@ module SimpleEnum
|
|
176
185
|
write_attribute options[:column], v
|
177
186
|
end
|
178
187
|
|
188
|
+
# support dirty attributes by delegating to column, currently opt-in
|
189
|
+
if options[:dirty]
|
190
|
+
define_method("#{enum_cd}_changed?") do
|
191
|
+
self.send("#{options[:column]}_changed?")
|
192
|
+
end
|
193
|
+
|
194
|
+
define_method("#{enum_cd}_was") do
|
195
|
+
values_inverted[self.send("#{options[:column]}_was")]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
179
199
|
# allow access to defined values hash, e.g. in a select helper or finder method.
|
180
200
|
attr_name = enum_cd.to_s.pluralize
|
181
201
|
enum_attr = :"#{attr_name.downcase}_enum_hash"
|
data/test/class_methods_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class ClassMethodsTest < ActiveSupport::TestCase
|
3
|
+
class ClassMethodsTest < ActiveSupport::TestCase
|
4
4
|
def setup
|
5
5
|
reload_db
|
6
6
|
end
|
@@ -12,7 +12,7 @@ class ClassMethodsTest < ActiveSupport::TestCase
|
|
12
12
|
assert_nil Dummy.genders[:inexistent]
|
13
13
|
assert_not_nil Dummy.genders[:female]
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
test "inheritance of `genders` to subclasses (#issue/3)" do
|
17
17
|
assert_equal({ :female => 1, :male => 0}, SpecificDummy.genders)
|
18
18
|
end
|
@@ -26,19 +26,24 @@ class ClassMethodsTest < ActiveSupport::TestCase
|
|
26
26
|
assert_equal [0, 1], Dummy.genders(:male, :female)
|
27
27
|
assert_equal [1, 0], Dummy.genders(:female, :male)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
|
+
test "inverted Hash returns synonym by code" do
|
31
|
+
assert_equal :male, Dummy.genders.invert[0]
|
32
|
+
assert_equal :female, Dummy.genders.invert[1]
|
33
|
+
end
|
34
|
+
|
30
35
|
test "generation of value shortcuts on class" do
|
31
36
|
g = Dummy.new
|
32
|
-
|
37
|
+
|
33
38
|
assert_equal 0, Dummy.male
|
34
39
|
assert_equal 1, Dummy.female
|
35
40
|
assert_equal 'alpha', Dummy.alpha
|
36
41
|
assert_respond_to Dummy, :male
|
37
42
|
assert_respond_to Dummy, :female
|
38
43
|
assert_respond_to Dummy, :beta
|
39
|
-
assert_respond_to Dummy, :foobar
|
44
|
+
assert_respond_to Dummy, :foobar
|
40
45
|
end
|
41
|
-
|
46
|
+
|
42
47
|
test "that no Klass.shortcut are created if :slim => true" do
|
43
48
|
class Dummy1 < ActiveRecord::Base
|
44
49
|
set_table_name 'dummies'
|
@@ -47,59 +52,59 @@ class ClassMethodsTest < ActiveSupport::TestCase
|
|
47
52
|
with_slim = Dummy1
|
48
53
|
|
49
54
|
assert !with_slim.respond_to?(:male)
|
50
|
-
assert !with_slim.respond_to?(:female)
|
55
|
+
assert !with_slim.respond_to?(:female)
|
51
56
|
assert_respond_to with_slim, :genders
|
52
57
|
end
|
53
|
-
|
58
|
+
|
54
59
|
test "that no Klass.shortcut's are created if :slim => :class, though instance shortcuts are" do
|
55
60
|
class Dummy2 < ActiveRecord::Base
|
56
61
|
set_table_name 'dummies'
|
57
62
|
as_enum :gender, [:male, :female], :slim => :class
|
58
63
|
end
|
59
64
|
with_slim_class = Dummy2
|
60
|
-
|
65
|
+
|
61
66
|
jane = with_slim_class.new
|
62
|
-
|
67
|
+
|
63
68
|
assert_respond_to jane, :male!
|
64
69
|
assert_respond_to jane, :female!
|
65
70
|
assert !with_slim_class.respond_to?(:male)
|
66
|
-
assert !with_slim_class.respond_to?(:female)
|
71
|
+
assert !with_slim_class.respond_to?(:female)
|
67
72
|
assert_respond_to with_slim_class, :genders
|
68
73
|
assert_same 0, with_slim_class.genders.male
|
69
74
|
assert_same 1, with_slim_class.genders[:female]
|
70
75
|
end
|
71
|
-
|
76
|
+
|
72
77
|
test "that Klass.shortcut respect :prefix => true and are prefixed by \#{enum_cd}" do
|
73
78
|
class Dummy3 < ActiveRecord::Base
|
74
79
|
set_table_name 'dummies'
|
75
80
|
as_enum :gender, [:male, :female], :prefix => true
|
76
81
|
end
|
77
82
|
with_prefix = Dummy3
|
78
|
-
|
83
|
+
|
79
84
|
assert !with_prefix.respond_to?(:male)
|
80
|
-
assert !with_prefix.respond_to?(:female)
|
85
|
+
assert !with_prefix.respond_to?(:female)
|
81
86
|
assert_respond_to with_prefix, :gender_male
|
82
87
|
assert_respond_to with_prefix, :gender_female
|
83
88
|
assert_equal 0, with_prefix.gender_male
|
84
89
|
assert_respond_to with_prefix, :genders
|
85
90
|
end
|
86
|
-
|
91
|
+
|
87
92
|
test "to ensure that Klass.shortcut also work with custom prefixes" do
|
88
93
|
class Dummy4 < ActiveRecord::Base
|
89
94
|
set_table_name 'dummies'
|
90
95
|
as_enum :gender, [:male, :female], :prefix => :g
|
91
96
|
end
|
92
97
|
with_custom_prefix = Dummy4
|
93
|
-
|
98
|
+
|
94
99
|
assert !with_custom_prefix.respond_to?(:male)
|
95
|
-
assert !with_custom_prefix.respond_to?(:female)
|
96
|
-
assert !with_custom_prefix.respond_to?(:gender_female)
|
100
|
+
assert !with_custom_prefix.respond_to?(:female)
|
101
|
+
assert !with_custom_prefix.respond_to?(:gender_female)
|
97
102
|
assert_respond_to with_custom_prefix, :g_male
|
98
103
|
assert_respond_to with_custom_prefix, :g_female
|
99
|
-
assert_equal 1, with_custom_prefix.g_female
|
100
|
-
assert_respond_to with_custom_prefix, :genders
|
104
|
+
assert_equal 1, with_custom_prefix.g_female
|
105
|
+
assert_respond_to with_custom_prefix, :genders
|
101
106
|
end
|
102
|
-
|
107
|
+
|
103
108
|
test "that the human_enum_name method returns translated/humanized values" do
|
104
109
|
assert_equal :male.to_s.humanize, Dummy.human_enum_name(:genders, :male)
|
105
110
|
assert_equal "Girl", Dummy.human_enum_name(:genders, :female)
|
@@ -114,10 +119,10 @@ class ClassMethodsTest < ActiveSupport::TestCase
|
|
114
119
|
assert_equal ["Male", :male], for_select.first
|
115
120
|
assert_equal ["Girl", :female], for_select.last
|
116
121
|
end
|
117
|
-
|
122
|
+
|
118
123
|
test "enum_for_select(:value) class method" do
|
119
124
|
for_select = Dummy.genders_for_select(:value)
|
120
125
|
assert_equal ["Male", 0], for_select.first
|
121
|
-
assert_equal ["Girl", 1], for_select.last
|
126
|
+
assert_equal ["Girl", 1], for_select.last
|
122
127
|
end
|
123
128
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DirtyDummy < ActiveRecord::Base
|
4
|
+
set_table_name 'dummies'
|
5
|
+
as_enum :gender, [:male, :female], :dirty => true
|
6
|
+
end
|
7
|
+
|
8
|
+
class DirtyAttributesTest < ActiveSupport::TestCase
|
9
|
+
def setup
|
10
|
+
reload_db
|
11
|
+
end
|
12
|
+
|
13
|
+
test "setting using changed? on enum" do
|
14
|
+
jane = DirtyDummy.create!(:gender => :female)
|
15
|
+
assert_equal 1, jane.gender_cd
|
16
|
+
jane.gender = :male # operation? =)
|
17
|
+
assert_equal :male, jane.gender
|
18
|
+
assert_equal true, jane.gender_cd_changed?
|
19
|
+
assert_equal true, jane.gender_changed?
|
20
|
+
end
|
21
|
+
|
22
|
+
test "access old value via gender_was" do
|
23
|
+
john = DirtyDummy.create!(:gender => :male)
|
24
|
+
assert_equal 0, john.gender_cd
|
25
|
+
john.gender = :female
|
26
|
+
assert_equal :female, john.gender
|
27
|
+
assert_equal 0, john.gender_cd_was
|
28
|
+
assert_equal :male, john.gender_was
|
29
|
+
end
|
30
|
+
|
31
|
+
test "dirty methods are disabled by default (opt-in)" do
|
32
|
+
no_dirty = Dummy.new
|
33
|
+
assert !no_dirty.respond_to?(:gender_was), "should not respond_to :gender_was"
|
34
|
+
assert !no_dirty.respond_to?(:gender_changed?), "should not respond_to :gender_changed?"
|
35
|
+
assert !no_dirty.respond_to?(:word_was), "should not respond_to :word_was"
|
36
|
+
assert !no_dirty.respond_to?(:word_changed?), "should not respond_to :word_changed?"
|
37
|
+
end
|
38
|
+
end
|
data/test/simple_enum_test.rb
CHANGED
@@ -203,4 +203,20 @@ class SimpleEnumTest < ActiveSupport::TestCase
|
|
203
203
|
d.gender = ''
|
204
204
|
assert_nil(d.gender)
|
205
205
|
end
|
206
|
+
|
207
|
+
test "deprecation warning when using enum name == column name" do
|
208
|
+
original_behavior = ActiveSupport::Deprecation.behavior
|
209
|
+
begin
|
210
|
+
expected = 0
|
211
|
+
ActiveSupport::Deprecation.silenced = false
|
212
|
+
ActiveSupport::Deprecation.behavior = Proc.new { |msg, cb| expected += 1 if msg =~ /\[simple_enum\].+gender_cd/ }
|
213
|
+
invalid_dummy = Class.new(ActiveRecord::Base) do
|
214
|
+
as_enum :gender_cd, [:male, :female], :column => "gender_cd"
|
215
|
+
end
|
216
|
+
|
217
|
+
assert expected == 1, "deprecation message not displayed"
|
218
|
+
ensure
|
219
|
+
ActiveSupport::Deprecation.behavior = original_behavior
|
220
|
+
end
|
221
|
+
end
|
206
222
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 1.4.
|
8
|
+
- 1
|
9
|
+
version: 1.4.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Lukas Westermann
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-09-
|
17
|
+
date: 2011-09-19 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- simple_enum.gemspec
|
108
108
|
- test/array_conversions_test.rb
|
109
109
|
- test/class_methods_test.rb
|
110
|
+
- test/dirty_attributes_test.rb
|
110
111
|
- test/enum_hash_test.rb
|
111
112
|
- test/finders_test.rb
|
112
113
|
- test/locales.yml
|
@@ -154,6 +155,7 @@ summary: Simple enum-like field support for active records.
|
|
154
155
|
test_files:
|
155
156
|
- test/array_conversions_test.rb
|
156
157
|
- test/class_methods_test.rb
|
158
|
+
- test/dirty_attributes_test.rb
|
157
159
|
- test/enum_hash_test.rb
|
158
160
|
- test/finders_test.rb
|
159
161
|
- test/locales.yml
|