classy_enum 2.3.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.md +12 -0
- data/README.md +22 -58
- data/classy_enum.gemspec +1 -1
- data/gemfiles/Gemfile.rails-3.0.x +2 -4
- data/gemfiles/Gemfile.rails-3.1.x +2 -4
- data/gemfiles/Gemfile.rails-3.2.x +2 -4
- data/lib/classy_enum/active_record.rb +58 -0
- data/lib/classy_enum/base.rb +83 -3
- data/lib/classy_enum/collection.rb +76 -0
- data/lib/classy_enum/conversion.rb +69 -0
- data/lib/classy_enum/predicate.rb +35 -0
- data/lib/classy_enum/version.rb +1 -1
- data/lib/classy_enum.rb +5 -8
- data/lib/generators/classy_enum/templates/enum.rb +0 -1
- data/spec/classy_enum/active_record_spec.rb +156 -0
- data/spec/classy_enum/base_spec.rb +50 -0
- data/spec/classy_enum/collection_spec.rb +32 -0
- data/spec/classy_enum/conversion_spec.rb +55 -0
- data/spec/classy_enum/predicate_spec.rb +19 -0
- data/spec/classy_enum_inheritance_spec.rb +28 -0
- data/spec/spec_helper.rb +0 -29
- metadata +21 -16
- data/lib/classy_enum/attributes.rb +0 -72
- data/lib/classy_enum/class_methods.rb +0 -141
- data/lib/classy_enum/instance_methods.rb +0 -122
- data/spec/active_record_spec.rb +0 -70
- data/spec/classy_enum_attributes_spec.rb +0 -97
- data/spec/classy_enum_owner_reference_spec.rb +0 -53
- data/spec/classy_enum_spec.rb +0 -105
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# ClassyEnum Changelog
|
2
2
|
|
3
|
+
## 3.0.0
|
4
|
+
|
5
|
+
* Removing ClassyEnum::Base.enum_classes in favor of using enum
|
6
|
+
inheritance to setup classes
|
7
|
+
* Removing ClassyEnum::Base.valid_options
|
8
|
+
* Removing ClassyEnum::Base.find
|
9
|
+
* Removing ClassyEnum::Base#name
|
10
|
+
* Removing :suffix option from classy_enum_attr
|
11
|
+
* Enforce use of namespacing for subclasses (Parent::Child < Parent)
|
12
|
+
* Use require instead of autoload
|
13
|
+
* Lots of code refactoring
|
14
|
+
|
3
15
|
## 2.3.0
|
4
16
|
|
5
17
|
* Deprecating ClassyEnum::Base#name (use to_s.titleize instead). `name` is
|
data/README.md
CHANGED
@@ -6,12 +6,12 @@ ClassyEnum is a Ruby on Rails gem that adds class-based enumerator functionality
|
|
6
6
|
|
7
7
|
## Rails & Ruby Versions Supported
|
8
8
|
|
9
|
-
*Rails:*
|
9
|
+
*Rails:* 3.0.x - 3.2.x
|
10
10
|
|
11
|
-
|
12
|
-
* 2.3.x: If you need support for Rails 2.3.x, please install [version 0.9.1](https://rubygems.org/gems/classy_enum/versions/0.9.1)
|
11
|
+
*Ruby:* 1.8.7, 1.9.2 and 1.9.3
|
13
12
|
|
14
|
-
|
13
|
+
If you need support for Rails 2.3.x, please install [version 0.9.1](https://rubygems.org/gems/classy_enum/versions/0.9.1).
|
14
|
+
Note: This branch is no longer maintained and will not get bug fixes or new features.
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
@@ -19,15 +19,9 @@ The gem is hosted at [rubygems.org](https://rubygems.org/gems/classy_enum)
|
|
19
19
|
|
20
20
|
You will also need to add `app/enums` as an autoloadable path. This configuration will depend on which version of rails you are using.
|
21
21
|
|
22
|
-
## Upgrading
|
22
|
+
## Upgrading?
|
23
23
|
|
24
|
-
|
25
|
-
when overriding methods or properties. As of 2.0, all enum classes must
|
26
|
-
explicity subclass a child of ClassyEnum::Base. If you used the
|
27
|
-
generator, there are no changes to the existing structure.
|
28
|
-
|
29
|
-
Built-in Formtastic support has been removed. See the note at the
|
30
|
-
bottom of this readme for more information how how to enable it.
|
24
|
+
See the [wiki](https://github.com/beerlington/classy_enum/wiki/Upgrading) for notes about upgrading from previous versions.
|
31
25
|
|
32
26
|
## Example Usage
|
33
27
|
|
@@ -45,20 +39,19 @@ A new enum template file will be created at app/enums/priority.rb that will look
|
|
45
39
|
|
46
40
|
```ruby
|
47
41
|
class Priority < ClassyEnum::Base
|
48
|
-
enum_classes :low, :medium, :high
|
49
42
|
end
|
50
43
|
|
51
|
-
class
|
44
|
+
class Priority::Low < Priority
|
52
45
|
end
|
53
46
|
|
54
|
-
class
|
47
|
+
class Priority::Medium < Priority
|
55
48
|
end
|
56
49
|
|
57
|
-
class
|
50
|
+
class Priority::High < Priority
|
58
51
|
end
|
59
52
|
```
|
60
53
|
|
61
|
-
The
|
54
|
+
The class order will define the enum member order as well as additional ClassyEnum behavior, which is described further down in this document.
|
62
55
|
|
63
56
|
### 2. Customize the Enum
|
64
57
|
|
@@ -70,20 +63,18 @@ I would like to add a method called `send_email?` that all member subclasses res
|
|
70
63
|
|
71
64
|
```ruby
|
72
65
|
class Priority < ClassyEnum::Base
|
73
|
-
enum_classes :low, :medium, :high
|
74
|
-
|
75
66
|
def send_email?
|
76
67
|
false
|
77
68
|
end
|
78
69
|
end
|
79
70
|
|
80
|
-
class
|
71
|
+
class Priority::Low < Priority
|
81
72
|
end
|
82
73
|
|
83
|
-
class
|
74
|
+
class Priority::Medium < Priority
|
84
75
|
end
|
85
76
|
|
86
|
-
class
|
77
|
+
class Priority::High < Priority
|
87
78
|
def send_email?
|
88
79
|
true
|
89
80
|
end
|
@@ -119,11 +110,10 @@ With this setup, I can now do the following:
|
|
119
110
|
```ruby
|
120
111
|
@alarm = Alarm.create(:priority => :medium)
|
121
112
|
|
122
|
-
@alarm.priority # =>
|
113
|
+
@alarm.priority # => Priority::Medium
|
123
114
|
@alarm.priority.medium? # => true
|
124
115
|
@alarm.priority.high? # => false
|
125
116
|
@alarm.priority.to_s # => 'medium'
|
126
|
-
@alarm.priority.name # => 'Medium'
|
127
117
|
|
128
118
|
# Should this alarm send an email?
|
129
119
|
@alarm.send_email? # => false
|
@@ -137,7 +127,7 @@ The enum field works like any other model attribute. It can be mass-assigned usi
|
|
137
127
|
|
138
128
|
In some cases you may want an enum class to reference the owning object
|
139
129
|
(an instance of the active record model). Think of it as a `belongs_to`
|
140
|
-
relationship, where the enum
|
130
|
+
relationship, where the enum belongs to the model.
|
141
131
|
|
142
132
|
By default, the back reference can be called using `owner`.
|
143
133
|
If you want to refer to the owner by a different name, you must explicitly declare
|
@@ -147,14 +137,11 @@ Example using the default `owner` method:
|
|
147
137
|
|
148
138
|
```ruby
|
149
139
|
class Priority < ClassyEnum::Base
|
150
|
-
enum_classes :low, :medium, :high
|
151
140
|
end
|
152
141
|
|
153
|
-
...
|
154
142
|
# low and medium subclasses omitted
|
155
|
-
...
|
156
143
|
|
157
|
-
class
|
144
|
+
class Priority::High < Priority
|
158
145
|
def send_email?
|
159
146
|
owner.enabled?
|
160
147
|
end
|
@@ -165,15 +152,12 @@ Example where the owner reference is explicitly declared:
|
|
165
152
|
|
166
153
|
```ruby
|
167
154
|
class Priority < ClassyEnum::Base
|
168
|
-
enum_classes :low, :medium, :high
|
169
155
|
owner :alarm
|
170
156
|
end
|
171
157
|
|
172
|
-
...
|
173
158
|
# low and medium subclasses omitted
|
174
|
-
...
|
175
159
|
|
176
|
-
class
|
160
|
+
class Priority::High < Priority
|
177
161
|
def send_email?
|
178
162
|
alarm.enabled?
|
179
163
|
end
|
@@ -213,28 +197,15 @@ end
|
|
213
197
|
|
214
198
|
## Special Cases
|
215
199
|
|
216
|
-
What if your enum class name is not the same as your model's attribute name? No problem! Just use a second
|
200
|
+
What if your enum class name is not the same as your model's attribute name? No problem! Just use a second argument in `classy_enum_attr` to declare the attribute name. In this case, the model's attribute is called *alarm_priority*.
|
217
201
|
|
218
202
|
```ruby
|
219
203
|
class Alarm < ActiveRecord::Base
|
220
|
-
classy_enum_attr :alarm_priority, :enum =>
|
204
|
+
classy_enum_attr :alarm_priority, :enum => 'Priority'
|
221
205
|
end
|
222
206
|
|
223
207
|
@alarm = Alarm.create(:alarm_priority => :medium)
|
224
|
-
@alarm.alarm_priority # =>
|
225
|
-
```
|
226
|
-
|
227
|
-
If you would like the default getter method to return a string, you can
|
228
|
-
use the optional *:suffix* option for the enum getter:
|
229
|
-
|
230
|
-
```ruby
|
231
|
-
class Alarm < ActiveRecord::Base
|
232
|
-
classy_enum_attr :priority, :suffix => 'type'
|
233
|
-
end
|
234
|
-
|
235
|
-
alarm = Alarm.create(:priority => :high)
|
236
|
-
alarm.priority # => 'high'
|
237
|
-
alarm.priority_type # instance of PriorityHigh enum
|
208
|
+
@alarm.alarm_priority # => Priority::Medium
|
238
209
|
```
|
239
210
|
|
240
211
|
## Model Validation
|
@@ -265,20 +236,13 @@ end
|
|
265
236
|
|
266
237
|
While ClassyEnum was designed to be used directly with ActiveRecord, it can also be used outside of it. Here are some examples based on the enum class defined earlier in this document.
|
267
238
|
|
268
|
-
Instantiate an enum member subclass *
|
239
|
+
Instantiate an enum member subclass *Priority::Low*
|
269
240
|
|
270
241
|
```ruby
|
271
242
|
# These statements are all equivalent
|
272
243
|
low = Priority.build(:low)
|
273
244
|
low = Priority.build('low')
|
274
|
-
low = Priority.
|
275
|
-
low = PriorityLow.new
|
276
|
-
```
|
277
|
-
|
278
|
-
Get a list of the valid enum options
|
279
|
-
|
280
|
-
```ruby
|
281
|
-
Priority.valid_options # => low, medium, high
|
245
|
+
low = Priority::Low.new
|
282
246
|
```
|
283
247
|
|
284
248
|
## Formtastic Support
|
data/classy_enum.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
|
17
17
|
gem.add_dependency('rails', '>= 3.0')
|
18
18
|
|
19
|
-
gem.add_development_dependency('rspec-rails', '~> 2.
|
19
|
+
gem.add_development_dependency('rspec-rails', '~> 2.11.0')
|
20
20
|
gem.add_development_dependency('sqlite3', '~> 1.3.6')
|
21
21
|
gem.add_development_dependency('json', '~> 1.6.5')
|
22
22
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
3
|
gem 'rails', '~> 3.0.0'
|
4
|
-
gem 'rspec-rails', '~> 2.
|
5
|
-
gem 'formtastic', '~> 1.2.4'
|
4
|
+
gem 'rspec-rails', '~> 2.11.0'
|
6
5
|
gem 'sqlite3-ruby', :require => 'sqlite3'
|
7
|
-
gem 'json', '~> 1.6.5'
|
8
|
-
gem "jeweler", "~> 1.6.2"
|
6
|
+
gem 'json', '~> 1.6.5'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ClassyEnum
|
2
|
+
module ActiveRecord
|
3
|
+
|
4
|
+
# Class macro used to associate an enum with an attribute on an ActiveRecord model.
|
5
|
+
# This method is automatically added to all ActiveRecord models when the classy_enum gem
|
6
|
+
# is installed. Accepts an argument for the enum class to be associated with
|
7
|
+
# the model. ActiveRecord validation is automatically added to ensure
|
8
|
+
# that a value is one of its pre-defined enum members.
|
9
|
+
#
|
10
|
+
# ==== Example
|
11
|
+
# # Associate an enum Priority with Alarm model's priority attribute
|
12
|
+
# class Alarm < ActiveRecord::Base
|
13
|
+
# classy_enum_attr :priority
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # Associate an enum Priority with Alarm model's alarm_priority attribute
|
17
|
+
# classy_enum_attr :alarm_priority, :enum => 'Priority'
|
18
|
+
#
|
19
|
+
# # Allow enum value to be nil
|
20
|
+
# classy_enum_attr :priority, :allow_nil => true
|
21
|
+
#
|
22
|
+
# # Allow enum value to be blank
|
23
|
+
# classy_enum_attr :priority, :allow_blank => true
|
24
|
+
def classy_enum_attr(attribute, options={})
|
25
|
+
enum = (options[:enum] || attribute).to_s.camelize.constantize
|
26
|
+
allow_blank = options[:allow_blank] || false
|
27
|
+
allow_nil = options[:allow_nil] || false
|
28
|
+
serialize_as_json = options[:serialize_as_json] || false
|
29
|
+
|
30
|
+
error_message = "must be #{enum.all.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ')}"
|
31
|
+
|
32
|
+
# Add ActiveRecord validation to ensure it won't be saved unless it's an option
|
33
|
+
validates_inclusion_of attribute,
|
34
|
+
:in => enum.all,
|
35
|
+
:message => error_message,
|
36
|
+
:allow_blank => allow_blank,
|
37
|
+
:allow_nil => allow_nil
|
38
|
+
|
39
|
+
# Define getter method that returns a ClassyEnum instance
|
40
|
+
define_method attribute do
|
41
|
+
enum.build(read_attribute(attribute),
|
42
|
+
:owner => self,
|
43
|
+
:serialize_as_json => serialize_as_json,
|
44
|
+
:allow_blank => (allow_blank || allow_nil)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Define setter method that accepts either string or symbol for member
|
49
|
+
define_method "#{attribute}=" do |value|
|
50
|
+
value = value.to_s unless value.nil?
|
51
|
+
super(value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
ActiveRecord::Base.send :extend, ClassyEnum::ActiveRecord
|
data/lib/classy_enum/base.rb
CHANGED
@@ -1,8 +1,88 @@
|
|
1
1
|
module ClassyEnum
|
2
|
+
class SubclassNameError < Exception; end
|
3
|
+
|
2
4
|
class Base
|
3
|
-
extend ClassyEnum::ClassMethods
|
4
|
-
include ClassyEnum::InstanceMethods
|
5
5
|
include Comparable
|
6
|
-
include
|
6
|
+
include Conversion
|
7
|
+
include Predicate
|
8
|
+
include Collection
|
9
|
+
|
10
|
+
class_attribute :base_class
|
11
|
+
attr_accessor :owner, :serialize_as_json, :allow_blank
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def inherited(klass)
|
15
|
+
if self == ClassyEnum::Base
|
16
|
+
klass.base_class = klass
|
17
|
+
else
|
18
|
+
|
19
|
+
# Ensure subclasses follow expected naming conventions
|
20
|
+
unless klass.name.start_with? "#{base_class.name}::"
|
21
|
+
raise SubclassNameError, "subclass must be namespaced with #{base_class.name}::"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add visit_EnumMember methods to support validates_uniqueness_of with enum field
|
25
|
+
# This is due to a bug in Rails where it uses the method result as opposed to the
|
26
|
+
# database value for validation scopes. A fix will be released in Rails 4, but
|
27
|
+
# this will remain until Rails 3.x is no longer prevalent.
|
28
|
+
Arel::Visitors::ToSql.class_eval do
|
29
|
+
define_method "visit_#{klass.name.split('::').join('_')}", lambda {|value| quote(value.to_s) }
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert from MyEnumClass::NumberTwo to :number_two
|
33
|
+
enum = klass.name.split('::').last.underscore.to_sym
|
34
|
+
|
35
|
+
Predicate.define_predicate_method(klass, enum)
|
36
|
+
|
37
|
+
klass.instance_variable_set('@option', enum)
|
38
|
+
end
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# Used internally to build a new ClassyEnum child instance
|
44
|
+
# It is preferred that you use ChildClass.new instead
|
45
|
+
#
|
46
|
+
# ==== Example
|
47
|
+
# # Create an Enum with some elements
|
48
|
+
# class Priority < ClassyEnum::Base
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# class Priority::Low < Priority
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Priority.build(:low) # => Priority::Low.new
|
55
|
+
# Priority.build(:invalid_option) # => :invalid_option
|
56
|
+
def build(value, options={})
|
57
|
+
return value if value.blank? && options[:allow_blank]
|
58
|
+
|
59
|
+
# Return the value if it is not a valid member
|
60
|
+
return value unless all.map(&:to_s).include? value.to_s
|
61
|
+
|
62
|
+
object = "#{base_class}::#{value.to_s.camelize}".constantize.new
|
63
|
+
object.owner = options[:owner]
|
64
|
+
object.serialize_as_json = options[:serialize_as_json]
|
65
|
+
object.allow_blank = options[:allow_blank]
|
66
|
+
object
|
67
|
+
end
|
68
|
+
|
69
|
+
# DSL setter method for overriding reference to enum owner (ActiveRecord model)
|
70
|
+
#
|
71
|
+
# ==== Example
|
72
|
+
# # Create an Enum with some elements
|
73
|
+
# class Priority < ClassyEnum::Base
|
74
|
+
# owner :alarm
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# class Priority::High < Priority
|
78
|
+
# def send_alarm?
|
79
|
+
# alarm.enabled?
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
def owner(owner)
|
83
|
+
define_method owner, lambda { @owner }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
7
87
|
end
|
8
88
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module ClassyEnum
|
2
|
+
module Collection
|
3
|
+
# Sort an array of elements based on the order they are defined
|
4
|
+
#
|
5
|
+
# ==== Example
|
6
|
+
# # Create an Enum with some elements
|
7
|
+
# class Priority < ClassyEnum::Base
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# class Priority::Low < Priority; end
|
11
|
+
# class Priority::Medium < Priority; end
|
12
|
+
# class Priority::High < Priority; end
|
13
|
+
#
|
14
|
+
# @low = Priority.build(:low)
|
15
|
+
# @medium = Priority.build(:medium)
|
16
|
+
# @high = Priority.build(:high)
|
17
|
+
# priorities = [@low, @high, @medium]
|
18
|
+
# priorities.sort # => [@low, @medium, @high]
|
19
|
+
# priorities.max # => @high
|
20
|
+
# priorities.min # => @low
|
21
|
+
def <=> other
|
22
|
+
index <=> other.index
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(klass)
|
26
|
+
klass.extend ClassMethods
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def inherited(klass)
|
31
|
+
if self == ClassyEnum::Base
|
32
|
+
klass.class_attribute :enum_options
|
33
|
+
klass.enum_options = []
|
34
|
+
else
|
35
|
+
enum_options << klass
|
36
|
+
klass.instance_variable_set('@index', enum_options.size)
|
37
|
+
end
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns an array of all instantiated enums
|
43
|
+
#
|
44
|
+
# ==== Example
|
45
|
+
# # Create an Enum with some elements
|
46
|
+
# class Priority < ClassyEnum::Base
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# class Priority::Low < Priority; end
|
50
|
+
# class Priority::Medium < Priority; end
|
51
|
+
# class Priority::High < Priority; end
|
52
|
+
#
|
53
|
+
# Priority.all # => [Priority::Low.new, Priority::Medium.new, Priority::High.new]
|
54
|
+
def all
|
55
|
+
enum_options.map(&:new)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a 2D array for Rails select helper options.
|
59
|
+
# Also used internally for Formtastic support
|
60
|
+
#
|
61
|
+
# ==== Example
|
62
|
+
# # Create an Enum with some elements
|
63
|
+
# class Priority < ClassyEnum::Base
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# class Priority::Low < Priority; end
|
67
|
+
# class Priority::ReallyHigh < Priority; end
|
68
|
+
#
|
69
|
+
# Priority.select_options # => [["Low", "low"], ["Really High", "really_high"]]
|
70
|
+
def select_options
|
71
|
+
all.map {|e| [e.to_s.titleize, e.to_s] }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module ClassyEnum
|
2
|
+
module Conversion
|
3
|
+
|
4
|
+
# Returns an integer representing the order that this element was defined in.
|
5
|
+
# Also used internally for sorting.
|
6
|
+
#
|
7
|
+
# ==== Example
|
8
|
+
# # Create an Enum with some elements
|
9
|
+
# class Priority < ClassyEnum::Base
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# class Priority::Low < Priority; end
|
13
|
+
# class Priority::Medium < Priority; end
|
14
|
+
# class Priority::High < Priority; end
|
15
|
+
#
|
16
|
+
# @priority = Priority::Medium.new
|
17
|
+
# @priority.to_i # => 2
|
18
|
+
def to_i
|
19
|
+
self.class.instance_variable_get('@index')
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :index :to_i
|
23
|
+
|
24
|
+
# Returns the name or string corresponding to element
|
25
|
+
#
|
26
|
+
# ==== Example
|
27
|
+
# # Create an Enum with some elements
|
28
|
+
# class Priority < ClassyEnum::Base
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# class Priority::Low < Priority; end
|
32
|
+
# class Priority::Medium < Priority; end
|
33
|
+
# class Priority::High < Priority; end
|
34
|
+
#
|
35
|
+
# @priority = Priority::Low.new
|
36
|
+
# @priority.to_s # => 'low'
|
37
|
+
def to_s
|
38
|
+
self.class.instance_variable_get('@option').to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a Symbol corresponding to a string representation of element,
|
42
|
+
# creating the symbol if it did not previously exist
|
43
|
+
#
|
44
|
+
# ==== Example
|
45
|
+
# # Create an Enum with some elements
|
46
|
+
# class Priority < ClassyEnum::Base
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# class Priority::Low < Priority; end
|
50
|
+
# class Priority::Medium < Priority; end
|
51
|
+
# class Priority::High < Priority; end
|
52
|
+
#
|
53
|
+
# @priority = Priority::Low.new
|
54
|
+
# @priority.to_sym # => :low
|
55
|
+
def to_sym
|
56
|
+
to_s.to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
# Overrides as_json to remove owner reference recursion issues
|
60
|
+
def as_json(options=nil)
|
61
|
+
return to_s unless serialize_as_json
|
62
|
+
json = super(options)
|
63
|
+
json.delete('owner')
|
64
|
+
json.delete('serialize_as_json')
|
65
|
+
json
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ClassyEnum
|
2
|
+
module Predicate
|
3
|
+
|
4
|
+
# Define attribute methods like two?
|
5
|
+
def self.define_predicate_method(klass, enum)
|
6
|
+
klass.base_class.class_eval do
|
7
|
+
define_method "#{enum}?", lambda { attribute?(enum.to_s) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
# Determine if the enum attribute is a particular member.
|
14
|
+
#
|
15
|
+
# ==== Example
|
16
|
+
# # Create an Enum with some elements
|
17
|
+
# class Breed < ClassyEnum::Base
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# class Breed::GoldenRetriever < Breed; end
|
21
|
+
# class Breed::Snoop < Breed; end
|
22
|
+
#
|
23
|
+
# # Create an ActiveRecord class using the Breed enum
|
24
|
+
# class Dog < ActiveRecord::Base
|
25
|
+
# classy_enum_attr :breed
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @dog = Dog.new(:breed => :snoop)
|
29
|
+
# @dog.breed.snoop? # => true
|
30
|
+
# @dog.breed.golden_retriever? # => false
|
31
|
+
def attribute?(attribute)
|
32
|
+
to_s == attribute
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/classy_enum/version.rb
CHANGED
data/lib/classy_enum.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
ActiveRecord::Base.send :extend, ClassyEnum::Attributes
|
1
|
+
require 'classy_enum/collection'
|
2
|
+
require 'classy_enum/conversion'
|
3
|
+
require 'classy_enum/predicate'
|
4
|
+
require 'classy_enum/base'
|
5
|
+
require 'classy_enum/active_record'
|