classy_enum 3.1.3 → 3.2.0
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/CHANGELOG.md +32 -7
- data/README.md +40 -9
- data/classy_enum.gemspec +3 -3
- data/lib/classy_enum/active_record.rb +19 -1
- data/lib/classy_enum/collection.rb +16 -0
- data/lib/classy_enum/version.rb +1 -1
- data/spec/classy_enum/active_record_spec.rb +57 -14
- data/spec/classy_enum/collection_spec.rb +6 -0
- data/spec/spec_helper.rb +0 -33
- metadata +10 -10
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
# ClassyEnum Changelog
|
2
2
|
|
3
|
+
## 3.2.0
|
4
|
+
|
5
|
+
* Default values can now be specified within an ActiveRecord model
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
class Alarm < ActiveRecord::Base
|
9
|
+
classy_enum_attr :priority, :default => 'medium'
|
10
|
+
end
|
11
|
+
|
12
|
+
class Alarm < ActiveRecord::Base
|
13
|
+
classy_enum_attr :priority, :default => lambda {|enum| enum.last }
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
* Adding ClassyEnum::Base#last. It's not part of the enumerable module
|
18
|
+
but it makes sense in this case.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
Priority.last # => Priority::High
|
22
|
+
```
|
23
|
+
|
3
24
|
## 3.1.3
|
4
25
|
|
5
26
|
* Fixes saving and reloading ActiveRecord models that assign enum using
|
@@ -10,8 +31,10 @@
|
|
10
31
|
* Allow enum property to be assigned using enum class. Previously it
|
11
32
|
could only be assigned with an instance, string or symbol.
|
12
33
|
|
13
|
-
|
14
|
-
|
34
|
+
```ruby
|
35
|
+
@alarm.priority = Priority::Medium
|
36
|
+
@alarm.priority.medium? # => true
|
37
|
+
```
|
15
38
|
|
16
39
|
## 3.1.1
|
17
40
|
|
@@ -33,8 +56,10 @@
|
|
33
56
|
* Equality can now be determined using strings and symbols. The
|
34
57
|
following will return true:
|
35
58
|
|
36
|
-
|
37
|
-
|
59
|
+
```ruby
|
60
|
+
Priority::Low.new == :low # => true
|
61
|
+
Priority::Low.new == 'low' # => true
|
62
|
+
```
|
38
63
|
|
39
64
|
## 3.0.0
|
40
65
|
|
@@ -62,9 +87,9 @@
|
|
62
87
|
|
63
88
|
## 2.1.0
|
64
89
|
|
65
|
-
* Deprecating ClassyEnum::Base.enum_classes
|
66
|
-
* Deprecating ClassyEnum::Base.valid_options(
|
67
|
-
* Deprecating ClassEnum::Base.find
|
90
|
+
* Deprecating ClassyEnum::Base.enum_classes (this is no longer needed)
|
91
|
+
* Deprecating ClassyEnum::Base.valid_options (use all.join(', ') instead)
|
92
|
+
* Deprecating ClassEnum::Base.find (use build() instead)
|
68
93
|
|
69
94
|
## 2.0.3
|
70
95
|
|
data/README.md
CHANGED
@@ -1,23 +1,26 @@
|
|
1
1
|
# ClassyEnum
|
2
2
|
|
3
3
|
[](http://travis-ci.org/beerlington/classy_enum)
|
4
|
+
[](http://badge.fury.io/rb/classy_enum)
|
5
|
+
[](https://codeclimate.com/github/beerlington/classy_enum)
|
4
6
|
|
5
7
|
ClassyEnum is a Ruby on Rails gem that adds class-based enumerator functionality to ActiveRecord attributes.
|
6
8
|
|
7
9
|
## README Topics
|
8
10
|
|
9
|
-
* [Example Usage](
|
10
|
-
* [Internationalization](
|
11
|
-
* [Using Enum as a Collection](
|
12
|
-
* [
|
13
|
-
* [
|
14
|
-
* [
|
15
|
-
* [
|
16
|
-
* [
|
11
|
+
* [Example Usage](#example-usage)
|
12
|
+
* [Internationalization](#internationalization)
|
13
|
+
* [Using Enum as a Collection](#using-enum-as-a-collection)
|
14
|
+
* [Default Enum Value](#default-enum-value)
|
15
|
+
* [Reference to Owning Object](#back-reference-to-owning-object)
|
16
|
+
* [Serializing as JSON](#serializing-as-json)
|
17
|
+
* [Special Cases](#special-cases)
|
18
|
+
* [Built-in Model Validation](#model-validation)
|
19
|
+
* [Formtastic Support](#formtastic-support)
|
17
20
|
|
18
21
|
## Rails & Ruby Versions Supported
|
19
22
|
|
20
|
-
*Rails:* 3.0.x -
|
23
|
+
*Rails:* 3.0.x - 4.0.0.beta
|
21
24
|
|
22
25
|
*Ruby:* 1.8.7, 1.9.2 and 1.9.3
|
23
26
|
|
@@ -187,6 +190,34 @@ Priority.each do |priority|
|
|
187
190
|
end
|
188
191
|
```
|
189
192
|
|
193
|
+
## Default Enum Value
|
194
|
+
|
195
|
+
As with any ActiveRecord attribute, default values can be specified in
|
196
|
+
the database table and will propagate to new instances. However, there
|
197
|
+
may be times when you can't or don't want to set the default value in
|
198
|
+
the database. For these occasions, a default value can be specified like
|
199
|
+
so:
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
class Alarm < ActiveRecord::Base
|
203
|
+
classy_enum_attr :priority, :default => 'medium'
|
204
|
+
end
|
205
|
+
|
206
|
+
Alarm.new.priority # => Priority::Medium
|
207
|
+
```
|
208
|
+
|
209
|
+
You may also use a Proc object to set the default value. The enum class
|
210
|
+
is yielded to the block and can be used to determine the default at
|
211
|
+
runtime.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class Alarm < ActiveRecord::Base
|
215
|
+
classy_enum_attr :priority, :default => lambda {|enum| enum.max }
|
216
|
+
end
|
217
|
+
|
218
|
+
Alarm.new.priority # => Priority::High
|
219
|
+
```
|
220
|
+
|
190
221
|
## Back reference to owning object
|
191
222
|
|
192
223
|
In some cases you may want an enum class to reference the owning object
|
data/classy_enum.gemspec
CHANGED
@@ -16,8 +16,8 @@ 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.11
|
20
|
-
gem.add_development_dependency('sqlite3', '~> 1.3
|
21
|
-
gem.add_development_dependency('json', '~> 1.6
|
19
|
+
gem.add_development_dependency('rspec-rails', '~> 2.11')
|
20
|
+
gem.add_development_dependency('sqlite3', '~> 1.3')
|
21
|
+
gem.add_development_dependency('json', '~> 1.6')
|
22
22
|
|
23
23
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module ClassyEnum
|
2
|
+
class InvalidDefault < StandardError; end
|
3
|
+
|
2
4
|
module ActiveRecord
|
3
5
|
|
4
6
|
# Class macro used to associate an enum with an attribute on an ActiveRecord model.
|
@@ -21,11 +23,25 @@ module ClassyEnum
|
|
21
23
|
#
|
22
24
|
# # Allow enum value to be blank
|
23
25
|
# classy_enum_attr :priority, :allow_blank => true
|
26
|
+
#
|
27
|
+
# # Specifying a default enum value
|
28
|
+
# classy_enum_attr :priority, :default => 'low'
|
24
29
|
def classy_enum_attr(attribute, options={})
|
25
30
|
enum = (options[:enum] || attribute).to_s.camelize.constantize
|
26
31
|
allow_blank = options[:allow_blank] || false
|
27
32
|
allow_nil = options[:allow_nil] || false
|
28
33
|
serialize_as_json = options[:serialize_as_json] || false
|
34
|
+
default = options[:default]
|
35
|
+
|
36
|
+
if default.present?
|
37
|
+
if default.is_a? Proc
|
38
|
+
default = default.call(enum)
|
39
|
+
end
|
40
|
+
|
41
|
+
unless enum.include? default
|
42
|
+
raise InvalidDefault, "must be one of [#{enum.to_a.join(',')}]"
|
43
|
+
end
|
44
|
+
end
|
29
45
|
|
30
46
|
# Add ActiveRecord validation to ensure it won't be saved unless it's an option
|
31
47
|
validates_inclusion_of attribute,
|
@@ -35,7 +51,9 @@ module ClassyEnum
|
|
35
51
|
|
36
52
|
# Define getter method that returns a ClassyEnum instance
|
37
53
|
define_method attribute do
|
38
|
-
|
54
|
+
value = read_attribute(attribute) || default
|
55
|
+
|
56
|
+
enum.build(value,
|
39
57
|
:owner => self,
|
40
58
|
:serialize_as_json => serialize_as_json,
|
41
59
|
:allow_blank => (allow_blank || allow_nil)
|
@@ -64,6 +64,22 @@ module ClassyEnum
|
|
64
64
|
enum_options.each {|e| yield e.new }
|
65
65
|
end
|
66
66
|
|
67
|
+
# Returns the last enum instance in the collection
|
68
|
+
#
|
69
|
+
# ==== Example
|
70
|
+
# # Create an Enum with some elements
|
71
|
+
# class Priority < ClassyEnum::Base
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# class Priority::Low < Priority; end
|
75
|
+
# class Priority::Medium < Priority; end
|
76
|
+
# class Priority::High < Priority; end
|
77
|
+
#
|
78
|
+
# Priority.last # => Priority::High
|
79
|
+
def last
|
80
|
+
to_a.last
|
81
|
+
end
|
82
|
+
|
67
83
|
# Finds an enum instance by symbol, string, or block.
|
68
84
|
#
|
69
85
|
# If a block is given, it passes each entry in enum to block, and returns
|
data/lib/classy_enum/version.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
|
+
ActiveRecord::Schema.define(:version => 1) do
|
4
|
+
create_table :dogs, :force => true do |t|
|
5
|
+
t.string :breed
|
6
|
+
t.string :other_breed
|
7
|
+
t.string :color
|
8
|
+
t.string :name
|
9
|
+
t.integer :age
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :cats, :force => true do |t|
|
13
|
+
t.string :breed
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
class Breed < ClassyEnum::Base; end
|
4
18
|
class Breed::GoldenRetriever < Breed; end
|
5
19
|
class Breed::Snoop < Breed; end
|
@@ -22,29 +36,31 @@ class CatBreed::Bengal < CatBreed; end
|
|
22
36
|
class CatBreed::Birman < CatBreed; end
|
23
37
|
class CatBreed::Persian < CatBreed; end
|
24
38
|
|
25
|
-
class Dog < ActiveRecord::Base
|
39
|
+
class Dog < ActiveRecord::Base; end
|
40
|
+
|
41
|
+
class DefaultDog < Dog
|
26
42
|
classy_enum_attr :breed
|
27
43
|
end
|
28
44
|
|
29
|
-
class AllowBlankBreedDog <
|
45
|
+
class AllowBlankBreedDog < Dog
|
30
46
|
classy_enum_attr :breed, :allow_blank => true
|
31
47
|
end
|
32
48
|
|
33
|
-
class AllowNilBreedDog <
|
49
|
+
class AllowNilBreedDog < Dog
|
34
50
|
classy_enum_attr :breed, :allow_nil => true
|
35
51
|
end
|
36
52
|
|
37
|
-
class OtherDog <
|
53
|
+
class OtherDog < Dog
|
38
54
|
classy_enum_attr :other_breed, :enum => 'Breed'
|
39
55
|
end
|
40
56
|
|
41
|
-
describe
|
42
|
-
specify {
|
43
|
-
specify {
|
57
|
+
describe DefaultDog do
|
58
|
+
specify { DefaultDog.new(:breed => nil).should_not be_valid }
|
59
|
+
specify { DefaultDog.new(:breed => '').should_not be_valid }
|
44
60
|
|
45
61
|
context "with valid breed options" do
|
46
62
|
[:golden_retriever, 'golden_retriever', Breed::GoldenRetriever.new, Breed::GoldenRetriever].each do |option|
|
47
|
-
subject {
|
63
|
+
subject { DefaultDog.new(:breed => option) }
|
48
64
|
it { should be_valid }
|
49
65
|
its(:breed) { should be_a(Breed::GoldenRetriever) }
|
50
66
|
its('breed.allow_blank') { should be_false }
|
@@ -58,7 +74,7 @@ describe Dog do
|
|
58
74
|
end
|
59
75
|
|
60
76
|
context "with invalid breed options" do
|
61
|
-
subject {
|
77
|
+
subject { DefaultDog.new(:breed => :fake_breed) }
|
62
78
|
it { should_not be_valid }
|
63
79
|
it { should have(1).error_on(:breed) }
|
64
80
|
end
|
@@ -103,10 +119,10 @@ describe "A ClassyEnum that has a different field name than the enum" do
|
|
103
119
|
its(:other_breed) { should be_a(Breed::Snoop) }
|
104
120
|
end
|
105
121
|
|
106
|
-
class ActiveDog <
|
122
|
+
class ActiveDog < Dog
|
107
123
|
classy_enum_attr :color
|
108
124
|
validates_uniqueness_of :name, :scope => :color
|
109
|
-
scope :goldens, where(:breed => 'golden_retriever')
|
125
|
+
scope :goldens, lambda { where(:breed => 'golden_retriever') }
|
110
126
|
end
|
111
127
|
|
112
128
|
describe ActiveDog do
|
@@ -141,20 +157,47 @@ describe ActiveDog do
|
|
141
157
|
|
142
158
|
end
|
143
159
|
|
160
|
+
class DefaultValueDog < Dog
|
161
|
+
classy_enum_attr :breed, :default => :snoop
|
162
|
+
end
|
163
|
+
|
164
|
+
describe DefaultValueDog do
|
165
|
+
its(:breed) { should == :snoop }
|
166
|
+
end
|
167
|
+
|
168
|
+
class DynamicDefaultValueDog < Dog
|
169
|
+
classy_enum_attr :breed, :default => lambda { |enum| enum.max }
|
170
|
+
end
|
171
|
+
|
172
|
+
describe DynamicDefaultValueDog do
|
173
|
+
its(:breed) { should == :husky }
|
174
|
+
end
|
175
|
+
|
176
|
+
describe Dog, 'with invalid default value' do
|
177
|
+
it 'raises error with invalid default' do
|
178
|
+
expect {
|
179
|
+
Class.new(Dog) { classy_enum_attr :breed, :default => :nope }
|
180
|
+
}.to raise_error(ClassyEnum::InvalidDefault)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
144
184
|
class Cat < ActiveRecord::Base
|
185
|
+
end
|
186
|
+
|
187
|
+
class DefaultCat < Cat
|
145
188
|
classy_enum_attr :breed, :enum => 'CatBreed'
|
146
189
|
attr_accessor :color
|
147
190
|
delegate :breed_color, :to => :breed
|
148
191
|
end
|
149
192
|
|
150
|
-
class OtherCat <
|
193
|
+
class OtherCat < Cat
|
151
194
|
classy_enum_attr :breed, :enum => 'CatBreed', :serialize_as_json => true
|
152
195
|
attr_accessor :color
|
153
196
|
delegate :breed_color, :to => :breed
|
154
197
|
end
|
155
198
|
|
156
|
-
describe
|
157
|
-
let(:abyssian) {
|
199
|
+
describe DefaultCat do
|
200
|
+
let(:abyssian) { DefaultCat.new(:breed => :abyssian, :color => 'black') }
|
158
201
|
let(:persian) { OtherCat.new(:breed => :persian, :color => 'white') }
|
159
202
|
|
160
203
|
it 'should delegate breed color to breed with an ownership reference' do
|
@@ -26,6 +26,12 @@ describe ClassyEnum::Collection do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
context '.last' do
|
30
|
+
its(:last) { should == ClassyEnumCollection::Three.new }
|
31
|
+
its(:last) { should == :three }
|
32
|
+
its(:last) { should_not == :one }
|
33
|
+
end
|
34
|
+
|
29
35
|
context '#<=> (equality)' do
|
30
36
|
its(:first) { should == ClassyEnumCollection::One.new }
|
31
37
|
its(:first) { should == :one }
|
data/spec/spec_helper.rb
CHANGED
@@ -13,36 +13,3 @@ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":me
|
|
13
13
|
RSpec.configure do |config|
|
14
14
|
config.color_enabled = true
|
15
15
|
end
|
16
|
-
|
17
|
-
ActiveRecord::Schema.define(:version => 1) do
|
18
|
-
create_table :dogs, :force => true do |t|
|
19
|
-
t.string :breed
|
20
|
-
end
|
21
|
-
|
22
|
-
create_table :other_dogs, :force => true do |t|
|
23
|
-
t.string :other_breed
|
24
|
-
end
|
25
|
-
|
26
|
-
create_table :allow_blank_breed_dogs, :force => true do |t|
|
27
|
-
t.string :breed
|
28
|
-
end
|
29
|
-
|
30
|
-
create_table :allow_nil_breed_dogs, :force => true do |t|
|
31
|
-
t.string :breed
|
32
|
-
end
|
33
|
-
|
34
|
-
create_table :active_dogs, :force => true do |t|
|
35
|
-
t.string :breed
|
36
|
-
t.string :color
|
37
|
-
t.string :name
|
38
|
-
t.integer :age
|
39
|
-
end
|
40
|
-
|
41
|
-
create_table :cats, :force => true do |t|
|
42
|
-
t.string :breed
|
43
|
-
end
|
44
|
-
|
45
|
-
create_table :other_cats, :force => true do |t|
|
46
|
-
t.string :breed
|
47
|
-
end
|
48
|
-
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: classy_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.11
|
37
|
+
version: '2.11'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.11
|
45
|
+
version: '2.11'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: sqlite3
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.3
|
53
|
+
version: '1.3'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.3
|
61
|
+
version: '1.3'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: json
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.6
|
69
|
+
version: '1.6'
|
70
70
|
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.6
|
77
|
+
version: '1.6'
|
78
78
|
description: A utility that adds class based enum functionality to ActiveRecord attributes
|
79
79
|
email:
|
80
80
|
- github@lette.us
|
@@ -126,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
126
|
version: '0'
|
127
127
|
segments:
|
128
128
|
- 0
|
129
|
-
hash:
|
129
|
+
hash: 3178964087580650038
|
130
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
131
|
none: false
|
132
132
|
requirements:
|
@@ -135,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
135
|
version: '0'
|
136
136
|
segments:
|
137
137
|
- 0
|
138
|
-
hash:
|
138
|
+
hash: 3178964087580650038
|
139
139
|
requirements: []
|
140
140
|
rubyforge_project:
|
141
141
|
rubygems_version: 1.8.24
|