simple_enum 1.4.0 → 1.4.1

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.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)
@@ -1,5 +1,5 @@
1
1
  module SimpleEnum
2
2
 
3
3
  # +SimpleEnum+ version string.
4
- VERSION = "1.4.0"
4
+ VERSION = "1.4.1"
5
5
  end
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 :status, { :active => 1, :inactive => 0, :archived => 2, :deleted => 3 }, :column => 'status'
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"
@@ -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
@@ -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
- - 0
9
- version: 1.4.0
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-09 00:00:00 +02:00
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