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 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