Skip to content
This repository
Browse code

Changing ClassyEnum subclass name requirements

Instead of:

ParentChild < Parent
end

Use:

Parent::Child < Parent
end
  • Loading branch information...
commit 253d925655085cada52c15564a32d3a398d3cb81 1 parent e8111c0
Peter Brown authored
26 README.md
Source Rendered
@@ -47,13 +47,13 @@ A new enum template file will be created at app/enums/priority.rb that will look
47 47 class Priority < ClassyEnum::Base
48 48 end
49 49
50   -class PriorityLow < Priority
  50 +class Priority::Low < Priority
51 51 end
52 52
53   -class PriorityMedium < Priority
  53 +class Priority::Medium < Priority
54 54 end
55 55
56   -class PriorityHigh < Priority
  56 +class Priority::High < Priority
57 57 end
58 58 ```
59 59
@@ -74,13 +74,13 @@ class Priority < ClassyEnum::Base
74 74 end
75 75 end
76 76
77   -class PriorityLow < Priority
  77 +class Priority::Low < Priority
78 78 end
79 79
80   -class PriorityMedium < Priority
  80 +class Priority::Medium < Priority
81 81 end
82 82
83   -class PriorityHigh < Priority
  83 +class Priority::High < Priority
84 84 def send_email?
85 85 true
86 86 end
@@ -116,7 +116,7 @@ With this setup, I can now do the following:
116 116 ```ruby
117 117 @alarm = Alarm.create(:priority => :medium)
118 118
119   -@alarm.priority # => PriorityMedium
  119 +@alarm.priority # => Priority::Medium
120 120 @alarm.priority.medium? # => true
121 121 @alarm.priority.high? # => false
122 122 @alarm.priority.to_s # => 'medium'
@@ -150,7 +150,7 @@ end
150 150 # low and medium subclasses omitted
151 151 # ...
152 152
153   -class PriorityHigh < Priority
  153 +class Priority::High < Priority
154 154 def send_email?
155 155 owner.enabled?
156 156 end
@@ -168,7 +168,7 @@ end
168 168 # low and medium subclasses omitted
169 169 # ...
170 170
171   -class PriorityHigh < Priority
  171 +class Priority::High < Priority
172 172 def send_email?
173 173 alarm.enabled?
174 174 end
@@ -216,7 +216,7 @@ class Alarm < ActiveRecord::Base
216 216 end
217 217
218 218 @alarm = Alarm.create(:alarm_priority => :medium)
219   -@alarm.alarm_priority # => PriorityMedium
  219 +@alarm.alarm_priority # => Priority::Medium
220 220 ```
221 221
222 222 If you would like the default getter method to return a string, you can
@@ -229,7 +229,7 @@ end
229 229
230 230 alarm = Alarm.create(:priority => :high)
231 231 alarm.priority # => 'high'
232   -alarm.priority_type # instance of PriorityHigh enum
  232 +alarm.priority_type # instance of Priority::High enum
233 233 ```
234 234
235 235 ## Model Validation
@@ -260,13 +260,13 @@ end
260 260
261 261 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.
262 262
263   -Instantiate an enum member subclass *PriorityLow*
  263 +Instantiate an enum member subclass *Priority::Low*
264 264
265 265 ```ruby
266 266 # These statements are all equivalent
267 267 low = Priority.build(:low)
268 268 low = Priority.build('low')
269   -low = PriorityLow.new
  269 +low = Priority::Low.new
270 270 ```
271 271
272 272 Get a list of the valid enum options
12 lib/classy_enum/base.rb
@@ -17,17 +17,17 @@ def inherited(klass)
17 17 else
18 18
19 19 # Ensure subclasses follow expected naming conventions
20   - unless klass.name.start_with? base_class.name
21   - raise SubclassNameError, "subclass name must start with #{base_class.name}"
  20 + unless klass.name.start_with? "#{base_class.name}::"
  21 + raise SubclassNameError, "subclass must be namespaced with #{base_class.name}::"
22 22 end
23 23
24 24 # Add visit_EnumMember methods to support validates_uniqueness_of with enum field
25 25 Arel::Visitors::ToSql.class_eval do
26   - define_method "visit_#{klass.name}", lambda {|value| quote(value.to_s) }
  26 + define_method "visit_#{klass.name.split('::').join('_')}", lambda {|value| quote(value.to_s) }
27 27 end
28 28
29   - # Convert from MyEnumClassNumberTwo to :number_two
30   - enum = klass.name.gsub(klass.base_class.name, '').underscore.to_sym
  29 + # Convert from MyEnumClass::NumberTwo to :number_two
  30 + enum = klass.name.split('::').last.underscore.to_sym
31 31
32 32 Predicate.define_predicate_method(klass, enum)
33 33
@@ -56,7 +56,7 @@ def build(value, options={})
56 56 return TypeError.new("#{base_class} #{invalid_message}")
57 57 end
58 58
59   - object = ("#{base_class}#{value.to_s.camelize}").constantize.new
  59 + object = ("#{base_class}::#{value.to_s.camelize}").constantize.new
60 60 object.owner = options[:owner]
61 61 object.serialize_as_json = options[:serialize_as_json]
62 62 object
4 spec/active_record_spec.rb
@@ -3,9 +3,9 @@
3 3 class Color < ClassyEnum::Base
4 4 end
5 5
6   -class ColorWhite < Color; end;
  6 +class Color::White < Color; end;
7 7
8   -class ColorBlack < Color; end;
  8 +class Color::Black < Color; end;
9 9
10 10 class ActiveDog < ActiveRecord::Base
11 11 classy_enum_attr :breed, :suffix => 'type'
4 spec/classy_enum/attributes_spec.rb
@@ -6,7 +6,7 @@
6 6 subject { Dog.new(:breed => :golden_retriever) }
7 7
8 8 it { should be_valid }
9   - its(:breed) { should be_a(BreedGoldenRetriever) }
  9 + its(:breed) { should be_a(Breed::GoldenRetriever) }
10 10 its(:breed_options) { should eql({:enum => :breed, :allow_blank => false}) }
11 11 end
12 12
@@ -93,5 +93,5 @@
93 93
94 94 describe "A ClassyEnum that has a different field name than the enum" do
95 95 subject { OtherDog.new(:other_breed => :snoop) }
96   - its(:other_breed) { should be_a(BreedSnoop) }
  96 + its(:other_breed) { should be_a(Breed::Snoop) }
97 97 end
28 spec/classy_enum/base_spec.rb
... ... @@ -1,46 +1,46 @@
1 1 require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2 2
3   -class TestEnum < ClassyEnum::Base
  3 +class ClassyEnumBase < ClassyEnum::Base
4 4 end
5 5
6   -class TestEnumOne < TestEnum
  6 +class ClassyEnumBase::One < ClassyEnumBase
7 7 end
8 8
9   -class TestEnumTwo < TestEnum
  9 +class ClassyEnumBase::Two < ClassyEnumBase
10 10 end
11 11
12 12 describe ClassyEnum::Base do
13 13 context '.build' do
14 14 context 'invalid option' do
15   - subject { TestEnum.build(:invalid_option) }
  15 + subject { ClassyEnumBase.build(:invalid_option) }
16 16 its(:class) { should == TypeError }
17 17 end
18 18
19 19 context 'string option' do
20   - subject { TestEnum.build("one") }
21   - it { should be_a(TestEnumOne) }
  20 + subject { ClassyEnumBase.build("one") }
  21 + it { should be_a(ClassyEnumBase::One) }
22 22 end
23 23
24 24 context 'symbol option' do
25   - subject { TestEnum.build(:two) }
26   - it { should be_a(TestEnumTwo) }
  25 + subject { ClassyEnumBase.build(:two) }
  26 + it { should be_a(ClassyEnumBase::Two) }
27 27 end
28 28 end
29 29
30 30 context '.invalid_message' do
31   - TestEnum.invalid_message.should == 'must be one of one, two'
  31 + ClassyEnumBase.invalid_message.should == 'must be one of one, two'
32 32 end
33 33
34 34 context '#new' do
35   - subject { TestEnumOne }
36   - its(:new) { should be_a(TestEnumOne) }
37   - its(:new) { should == TestEnumOne.new }
  35 + subject { ClassyEnumBase::One }
  36 + its(:new) { should be_a(ClassyEnumBase::One) }
  37 + its(:new) { should == ClassyEnumBase::One.new }
38 38 end
39 39
40 40 context 'Subclass naming' do
41 41 it 'should raise an error when invalid' do
42 42 lambda {
43   - class WrongSublcassName < TestEnum; end
  43 + class WrongSublcassName < ClassyEnumBase; end
44 44 }.should raise_error(ClassyEnum::SubclassNameError)
45 45 end
46 46 end
@@ -48,6 +48,6 @@ class WrongSublcassName < TestEnum; end
48 48
49 49 describe ClassyEnum::Base, 'Arel visitor' do
50 50 specify do
51   - Arel::Visitors::ToSql.instance_methods.map(&:to_sym).should include(:visit_TestEnumOne, :visit_TestEnumTwo)
  51 + Arel::Visitors::ToSql.instance_methods.map(&:to_sym).should include(:'visit_ClassyEnumBase_One', :'visit_ClassyEnumBase_Two')
52 52 end
53 53 end
16 spec/classy_enum/collection_spec.rb
@@ -3,27 +3,27 @@
3 3 class ClassyEnumCollection < ClassyEnum::Base
4 4 end
5 5
6   -class ClassyEnumCollectionOne < ClassyEnumCollection
  6 +class ClassyEnumCollection::One < ClassyEnumCollection
7 7 end
8 8
9   -class ClassyEnumCollectionTwo < ClassyEnumCollection
  9 +class ClassyEnumCollection::Two < ClassyEnumCollection
10 10 end
11 11
12   -class ClassyEnumCollectionThree < ClassyEnumCollection
  12 +class ClassyEnumCollection::Three < ClassyEnumCollection
13 13 end
14 14
15 15 describe ClassyEnum::Collection do
16 16 subject { ClassyEnumCollection }
17 17
18   - its(:enum_options) { should == [ClassyEnumCollectionOne, ClassyEnumCollectionTwo, ClassyEnumCollectionThree] }
19   - its(:all) { should == [ClassyEnumCollectionOne.new, ClassyEnumCollectionTwo.new, ClassyEnumCollectionThree.new] }
  18 + its(:enum_options) { should == [ClassyEnumCollection::One, ClassyEnumCollection::Two, ClassyEnumCollection::Three] }
  19 + its(:all) { should == [ClassyEnumCollection::One.new, ClassyEnumCollection::Two.new, ClassyEnumCollection::Three.new] }
20 20 its(:select_options) { should == [['One', 'one'],['Two', 'two'], ['Three', 'three']] }
21 21 end
22 22
23 23 describe ClassyEnum::Collection, Comparable do
24   - let(:one) { ClassyEnumCollectionOne.new }
25   - let(:two) { ClassyEnumCollectionTwo.new }
26   - let(:three) { ClassyEnumCollectionThree.new }
  24 + let(:one) { ClassyEnumCollection::One.new }
  25 + let(:two) { ClassyEnumCollection::Two.new }
  26 + let(:three) { ClassyEnumCollection::Three.new }
27 27
28 28 subject { [one, three, two] }
29 29 its(:sort) { should eql([one, two, three]) }
28 spec/classy_enum/conversion_spec.rb
@@ -3,49 +3,49 @@
3 3 class ClassyEnumConversion < ClassyEnum::Base
4 4 end
5 5
6   -class ClassyEnumConversionOne < ClassyEnumConversion
  6 +class ClassyEnumConversion::One < ClassyEnumConversion
7 7 end
8 8
9   -class ClassyEnumConversionTwo < ClassyEnumConversion
  9 +class ClassyEnumConversion::Two < ClassyEnumConversion
10 10 end
11 11
12 12 describe ClassyEnum::Conversion do
13 13 context '#to_i' do
14   - specify { ClassyEnumConversionOne.new.to_i.should == 1 }
15   - specify { ClassyEnumConversionTwo.new.to_i.should == 2 }
  14 + specify { ClassyEnumConversion::One.new.to_i.should == 1 }
  15 + specify { ClassyEnumConversion::Two.new.to_i.should == 2 }
16 16 end
17 17
18 18 context '#index' do
19   - specify { ClassyEnumConversionOne.new.index.should == 1 }
20   - specify { ClassyEnumConversionTwo.new.index.should == 2 }
  19 + specify { ClassyEnumConversion::One.new.index.should == 1 }
  20 + specify { ClassyEnumConversion::Two.new.index.should == 2 }
21 21 end
22 22
23 23 context '#to_s' do
24   - specify { ClassyEnumConversionOne.new.to_s.should == 'one' }
25   - specify { ClassyEnumConversionTwo.new.to_s.should == 'two' }
  24 + specify { ClassyEnumConversion::One.new.to_s.should == 'one' }
  25 + specify { ClassyEnumConversion::Two.new.to_s.should == 'two' }
26 26 end
27 27
28 28 context '#to_sym' do
29   - specify { ClassyEnumConversionOne.new.to_sym.should == :one }
30   - specify { ClassyEnumConversionTwo.new.to_sym.should == :two }
  29 + specify { ClassyEnumConversion::One.new.to_sym.should == :one }
  30 + specify { ClassyEnumConversion::Two.new.to_sym.should == :two }
31 31 end
32 32
33 33 context '#as_json' do
34 34 context 'serialize_as_json is false' do
35   - specify { ClassyEnumConversionOne.new.as_json.should == 'one' }
36   - specify { ClassyEnumConversionTwo.new.as_json.should == 'two' }
  35 + specify { ClassyEnumConversion::One.new.as_json.should == 'one' }
  36 + specify { ClassyEnumConversion::Two.new.as_json.should == 'two' }
37 37 end
38 38
39 39 context 'serialize_as_json is true' do
40 40 specify do
41   - enum = ClassyEnumConversionOne.new
  41 + enum = ClassyEnumConversion::One.new
42 42 enum.serialize_as_json = true
43 43 enum.instance_variable_set('@key', 'value')
44 44 enum.as_json.should == {'key' => 'value' }
45 45 end
46 46
47 47 specify do
48   - enum = ClassyEnumConversionOne.new
  48 + enum = ClassyEnumConversion::One.new
49 49 enum.serialize_as_json = true
50 50 enum.instance_variable_set('@key', 'value')
51 51 enum.as_json.should == {'key' => 'value' }
12 spec/classy_enum/predicate_spec.rb
@@ -3,17 +3,17 @@
3 3 class ClassyEnumPredicate < ClassyEnum::Base
4 4 end
5 5
6   -class ClassyEnumPredicateOne < ClassyEnumPredicate
  6 +class ClassyEnumPredicate::One < ClassyEnumPredicate
7 7 end
8 8
9   -class ClassyEnumPredicateTwo < ClassyEnumPredicate
  9 +class ClassyEnumPredicate::Two < ClassyEnumPredicate
10 10 end
11 11
12 12 describe ClassyEnum::Predicate do
13 13 context '#attribute?' do
14   - specify { ClassyEnumPredicateOne.new.should be_one }
15   - specify { ClassyEnumPredicateOne.new.should_not be_two }
16   - specify { ClassyEnumPredicateTwo.new.should_not be_one }
17   - specify { ClassyEnumPredicateTwo.new.should be_two }
  14 + specify { ClassyEnumPredicate::One.new.should be_one }
  15 + specify { ClassyEnumPredicate::One.new.should_not be_two }
  16 + specify { ClassyEnumPredicate::Two.new.should_not be_one }
  17 + specify { ClassyEnumPredicate::Two.new.should be_two }
18 18 end
19 19 end
12 spec/classy_enum_inheritance_spec.rb
@@ -4,25 +4,25 @@ class ProjectTier < ClassyEnum::Base
4 4 class_attribute :inherited_properties
5 5 end
6 6
7   -class ProjectTierOne < ProjectTier
  7 +class ProjectTier::One < ProjectTier
8 8 self.inherited_properties = [1,2,3]
9 9 end
10 10
11   -class ProjectTierTwo < ProjectTierOne
  11 +class ProjectTier::Two < ProjectTier::One
12 12 self.inherited_properties += [4,5,6]
13 13 end
14 14
15 15 describe 'Classy Enum inheritance' do
16 16 it 'should inherit from the previous class' do
17   - ProjectTierOne.inherited_properties.should == [1,2,3]
18   - ProjectTierTwo.inherited_properties.should == [1,2,3,4,5,6]
  17 + ProjectTier::One.inherited_properties.should == [1,2,3]
  18 + ProjectTier::Two.inherited_properties.should == [1,2,3,4,5,6]
19 19 end
20 20
21 21 it 'should instantiate the subclass' do
22   - ProjectTierTwo.build(:two).should == ProjectTierTwo.new
  22 + ProjectTier::Two.build(:two).should == ProjectTier::Two.new
23 23 end
24 24
25 25 it 'should have the right index' do
26   - ProjectTierTwo.new.index.should == 2
  26 + ProjectTier::Two.new.index.should == 2
27 27 end
28 28 end
8 spec/classy_enum_owner_reference_spec.rb
@@ -8,16 +8,16 @@ def breed_color
8 8 end
9 9 end
10 10
11   -class CatBreedAbyssian < CatBreed
  11 +class CatBreed::Abyssian < CatBreed
12 12 end
13 13
14   -class CatBreedBengal < CatBreed
  14 +class CatBreed::Bengal < CatBreed
15 15 end
16 16
17   -class CatBreedBirman < CatBreed
  17 +class CatBreed::Birman < CatBreed
18 18 end
19 19
20   -class CatBreedPersian < CatBreed
  20 +class CatBreed::Persian < CatBreed
21 21 end
22 22
23 23 class Cat < ActiveRecord::Base
6 spec/spec_helper.rb
@@ -50,13 +50,13 @@
50 50 class Breed < ClassyEnum::Base
51 51 end
52 52
53   -class BreedGoldenRetriever < Breed
  53 +class Breed::GoldenRetriever < Breed
54 54 end
55 55
56   -class BreedSnoop < Breed
  56 +class Breed::Snoop < Breed
57 57 end
58 58
59   -class BreedHusky < Breed
  59 +class Breed::Husky < Breed
60 60 end
61 61
62 62 class Dog < ActiveRecord::Base

0 comments on commit 253d925

Please sign in to comment.
Something went wrong with that request. Please try again.