classy_enum 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +15 -2
- data/VERSION +1 -1
- data/classy_enum.gemspec +3 -3
- data/lib/classy_enum/attributes.rb +11 -6
- data/lib/classy_enum/semantic_form_builder.rb +4 -4
- data/spec/classy_enum_attributes_spec.rb +81 -0
- data/spec/classy_enum_semantic_form_builder_spec.rb +46 -41
- data/spec/spec_helper.rb +19 -0
- metadata +5 -5
data/README.textile
CHANGED
@@ -132,9 +132,9 @@ end
|
|
132
132
|
|
133
133
|
h2. Model Validation
|
134
134
|
|
135
|
-
An ActiveRecord validator @validates_inclusion_of :field, :in => ENUM.all
|
135
|
+
An ActiveRecord validator @validates_inclusion_of :field, :in => ENUM.all@ is automatically added to your model when you use @classy_enum_attr@.
|
136
136
|
|
137
|
-
If your enum only has members low,
|
137
|
+
If your enum only has members low, medium, and high, then the following validation behavior would be expected:
|
138
138
|
|
139
139
|
<pre>
|
140
140
|
@alarm = Alarm.new(:priority => :really_high)
|
@@ -143,6 +143,17 @@ If your enum only has members low, mediume, and high, then the following validat
|
|
143
143
|
@alarm.valid? # => true
|
144
144
|
</pre>
|
145
145
|
|
146
|
+
To allow nil or blank values, you can pass in :allow_nil and :allow_blank as options to classy_enum_attr, like so:
|
147
|
+
|
148
|
+
<pre>
|
149
|
+
class Alarm < ActiveRecord::Base
|
150
|
+
classy_enum_attr :priority, :allow_nil => true
|
151
|
+
end
|
152
|
+
|
153
|
+
@alarm = Alarm.new(:priority => nil)
|
154
|
+
@alarm.valid? # => true
|
155
|
+
</pre>
|
156
|
+
|
146
157
|
h2. Working with ClassyEnum outside of ActiveRecord
|
147
158
|
|
148
159
|
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.
|
@@ -173,6 +184,8 @@ Formtastic::SemanticFormHelper.builder = ClassyEnum::SemanticFormBuilder
|
|
173
184
|
|
174
185
|
Then in your Formtastic view forms, use this syntax: @<%= f.input :priority, :as => :enum_select %>@
|
175
186
|
|
187
|
+
Note: ClassyEnum respects the @:allow_blank@ and @:allow_nil@ options and will include a blank select option in these cases
|
188
|
+
|
176
189
|
h2. Copyright
|
177
190
|
|
178
191
|
Copyright (c) 2011 Peter Brown. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.1
|
data/classy_enum.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{classy_enum}
|
8
|
-
s.version = "0.8.
|
8
|
+
s.version = "0.8.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Peter Brown"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-26}
|
13
13
|
s.description = %q{A utility that adds class based enum functionality to ActiveRecord attributes}
|
14
14
|
s.email = %q{github@lette.us}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.homepage = %q{http://github.com/beerlington/classy_enum}
|
46
46
|
s.rdoc_options = ["--charset=UTF-8"]
|
47
47
|
s.require_paths = ["lib"]
|
48
|
-
s.rubygems_version = %q{1.6.
|
48
|
+
s.rubygems_version = %q{1.6.1}
|
49
49
|
s.summary = %q{A class based enumerator utility for Ruby on Rails}
|
50
50
|
s.test_files = [
|
51
51
|
"spec/classy_enum_attributes_spec.rb",
|
@@ -23,17 +23,16 @@ module ClassyEnum
|
|
23
23
|
|
24
24
|
attribute = args[0]
|
25
25
|
enum = options[:enum] || attribute
|
26
|
+
allow_blank = options[:allow_blank] || false
|
27
|
+
allow_nil = options[:allow_nil] || false
|
26
28
|
|
27
29
|
klass = enum.to_s.camelize.constantize
|
28
30
|
|
29
31
|
self.instance_eval do
|
30
32
|
|
31
|
-
# Store the enum class so it can be retrieved by Formtastic input builder
|
32
|
-
@classy_enums ||= {}
|
33
|
-
@classy_enums[attribute] = klass
|
34
|
-
|
35
33
|
# Add ActiveRecord validation to ensure it won't be saved unless it's an option
|
36
|
-
validates_inclusion_of attribute, :in => klass.all, :message => "must be one of #{klass.valid_options}"
|
34
|
+
validates_inclusion_of attribute, :in => klass.all, :message => "must be one of #{klass.valid_options}",
|
35
|
+
:allow_blank => allow_blank, :allow_nil => allow_nil
|
37
36
|
|
38
37
|
# Define getter method that returns a ClassyEnum instance
|
39
38
|
define_method attribute do
|
@@ -42,7 +41,13 @@ module ClassyEnum
|
|
42
41
|
|
43
42
|
# Define setter method that accepts either string or symbol for member
|
44
43
|
define_method "#{attribute}=" do |value|
|
45
|
-
|
44
|
+
value = value.to_s unless value.nil?
|
45
|
+
super(value)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Store the enum options so it can be later retrieved by Formtastic
|
49
|
+
define_method "#{attribute}_options" do
|
50
|
+
{:enum => enum, :allow_blank => allow_blank}
|
46
51
|
end
|
47
52
|
|
48
53
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ClassyEnum
|
2
2
|
class SemanticFormBuilder < Formtastic::SemanticFormBuilder # :nodoc: all
|
3
3
|
def enum_select_input(method, options)
|
4
|
-
|
4
|
+
raise Error.invalid_classy_enum_object(method) unless object.respond_to? "#{method}_options"
|
5
5
|
|
6
|
-
|
6
|
+
enum_options = object.send("#{method}_options")
|
7
|
+
enum_class = enum_options[:enum].to_s.classify.constantize
|
7
8
|
|
8
9
|
options[:collection] = enum_class.select_options
|
9
10
|
options[:selected] = object.send(method).to_s
|
10
|
-
|
11
|
-
options[:include_blank] = false
|
11
|
+
options[:include_blank] = enum_options[:allow_blank]
|
12
12
|
|
13
13
|
select_input(method, options)
|
14
14
|
end
|
@@ -12,6 +12,11 @@ describe "A Dog" do
|
|
12
12
|
it "should be valid with a valid option" do
|
13
13
|
@dog.should be_valid
|
14
14
|
end
|
15
|
+
|
16
|
+
it "should have the right classy options for breed" do
|
17
|
+
options = {:enum => :breed, :allow_blank => false}
|
18
|
+
@dog.breed_options.should == options
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
it "should not be valid with a nil breed" do
|
@@ -37,6 +42,82 @@ describe "A Dog" do
|
|
37
42
|
|
38
43
|
end
|
39
44
|
|
45
|
+
describe "A ClassyEnum that allows blanks" do
|
46
|
+
|
47
|
+
context "with valid breed options" do
|
48
|
+
before { @dog = AllowBlankBreedDog.new(:breed => :golden_retriever) }
|
49
|
+
|
50
|
+
it "should be valid with a valid option" do
|
51
|
+
@dog.should be_valid
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have the right classy options for breed" do
|
55
|
+
options = {:enum => :breed, :allow_blank => true}
|
56
|
+
@dog.breed_options.should == options
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should be valid with a nil breed" do
|
61
|
+
AllowBlankBreedDog.new(:breed => nil).should be_valid
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be valid with a blank breed" do
|
65
|
+
AllowBlankBreedDog.new(:breed => "").should be_valid
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with invalid breed options" do
|
69
|
+
before { @dog = AllowBlankBreedDog.new(:breed => :fake_breed) }
|
70
|
+
|
71
|
+
it "should not be valid with an invalid option" do
|
72
|
+
@dog.should_not be_valid
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should have an error message containing the right options" do
|
76
|
+
@dog.valid?
|
77
|
+
@dog.errors[:breed].should include("must be one of #{Breed.all.map(&:to_sym).join(', ')}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "A ClassyEnum that allows nils" do
|
84
|
+
|
85
|
+
context "with valid breed options" do
|
86
|
+
before { @dog = AllowNilBreedDog.new(:breed => :golden_retriever) }
|
87
|
+
|
88
|
+
it "should be valid with a valid option" do
|
89
|
+
@dog.should be_valid
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should have the right classy options for breed" do
|
93
|
+
options = {:enum => :breed, :allow_blank => false}
|
94
|
+
@dog.breed_options.should == options
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should be valid with a nil breed" do
|
99
|
+
AllowNilBreedDog.new(:breed => nil).should be_valid
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should not be valid with a blank breed" do
|
103
|
+
AllowNilBreedDog.new(:breed => "").should_not be_valid
|
104
|
+
end
|
105
|
+
|
106
|
+
context "with invalid breed options" do
|
107
|
+
before { @dog = AllowNilBreedDog.new(:breed => :fake_breed) }
|
108
|
+
|
109
|
+
it "should not be valid with an invalid option" do
|
110
|
+
@dog.should_not be_valid
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have an error message containing the right options" do
|
114
|
+
@dog.valid?
|
115
|
+
@dog.errors[:breed].should include("must be one of #{Breed.all.map(&:to_sym).join(', ')}")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
40
121
|
describe "A ClassyEnum that has a different field name than the enum" do
|
41
122
|
before { @dog = OtherDog.new(:other_breed => :snoop) }
|
42
123
|
|
@@ -5,86 +5,91 @@ describe 'using enum_select input' do
|
|
5
5
|
|
6
6
|
Formtastic::SemanticFormHelper.builder = ClassyEnum::SemanticFormBuilder
|
7
7
|
|
8
|
-
#
|
9
|
-
before
|
10
|
-
@output_buffer = ""
|
11
|
-
end
|
8
|
+
# Reset output buffer
|
9
|
+
before { @output_buffer = "" }
|
12
10
|
|
13
|
-
context
|
14
|
-
context
|
15
|
-
|
16
|
-
|
11
|
+
context 'when building a form with a classy_enum select' do
|
12
|
+
context 'with an object that has the enum set' do
|
13
|
+
let(:output) do
|
14
|
+
semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
|
17
15
|
concat(builder.input(:breed, :as => :enum_select))
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
|
-
it
|
22
|
-
|
23
|
-
@output.should =~ regex
|
19
|
+
it 'should produce an unselected option tag for Golden Retriever' do
|
20
|
+
output.should =~ Regexp.new(%q{option value="golden_retriever">Golden Retriever})
|
24
21
|
end
|
25
22
|
|
26
|
-
it
|
27
|
-
|
28
|
-
@output.should =~ regex
|
23
|
+
it 'should produce a selected option tag for Snoop' do
|
24
|
+
output.should =~ Regexp.new(%q{<option value="snoop" selected="selected">Snoop})
|
29
25
|
end
|
30
26
|
|
31
|
-
it
|
32
|
-
|
33
|
-
@output.should_not =~ regex
|
27
|
+
it 'should not produce a blank option tag' do
|
28
|
+
output.should_not =~ Regexp.new(%q{<option value=""><})
|
34
29
|
end
|
35
30
|
end
|
36
31
|
|
37
|
-
context
|
38
|
-
|
39
|
-
|
32
|
+
context 'with an object that has a nil enum' do
|
33
|
+
let(:output) do
|
34
|
+
semantic_form_for(Dog.new, :url => "/") do |builder|
|
40
35
|
concat(builder.input(:breed, :as => :enum_select))
|
41
36
|
end
|
42
37
|
end
|
43
38
|
|
44
|
-
it
|
45
|
-
|
46
|
-
@output.should =~ regex
|
39
|
+
it 'should produce an unselected option tag for Golden Retriever' do
|
40
|
+
output.should =~ Regexp.new(%q{<option value="golden_retriever">Golden Retriever})
|
47
41
|
end
|
48
42
|
|
49
|
-
it
|
50
|
-
|
51
|
-
@output.should_not =~ regex
|
43
|
+
it 'should not produce an selected option tag' do
|
44
|
+
output.should_not =~ Regexp.new("selected")
|
52
45
|
end
|
53
|
-
|
54
46
|
end
|
55
47
|
|
56
|
-
context
|
57
|
-
|
58
|
-
|
59
|
-
concat(builder.input(:
|
48
|
+
context 'with an object that allows blank enums' do
|
49
|
+
let(:output) do
|
50
|
+
semantic_form_for(AllowBlankBreedDog.new, :url => "/") do |builder|
|
51
|
+
concat(builder.input(:breed, :as => :enum_select))
|
60
52
|
end
|
61
53
|
end
|
62
54
|
|
63
|
-
it
|
64
|
-
|
65
|
-
@output.should =~ regex
|
55
|
+
it 'should produce an unselected option tag for Golden Retriever' do
|
56
|
+
output.should =~ Regexp.new(%q{<option value="golden_retriever">Golden Retriever})
|
66
57
|
end
|
67
58
|
|
68
|
-
it
|
69
|
-
|
70
|
-
@output.should_not =~ regex
|
59
|
+
it 'should produce a blank option tag' do
|
60
|
+
output.should =~ Regexp.new(%q{<option value=""><})
|
71
61
|
end
|
62
|
+
end
|
72
63
|
|
64
|
+
context 'with an object that allows nil enums' do
|
65
|
+
let(:output) do
|
66
|
+
semantic_form_for(AllowNilBreedDog.new, :url => "/") do |builder|
|
67
|
+
concat(builder.input(:breed, :as => :enum_select))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should produce an unselected option tag for Golden Retriever' do
|
72
|
+
output.should =~ Regexp.new(%q{<option value="golden_retriever">Golden Retriever})
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should produce a blank option tag' do
|
76
|
+
output.should_not =~ Regexp.new(%q{<option value=""><})
|
77
|
+
end
|
73
78
|
end
|
74
79
|
|
75
80
|
end
|
76
81
|
|
77
|
-
it
|
82
|
+
it 'should raise an error if the attribute is not a ClassyEnum object' do
|
78
83
|
lambda do
|
79
|
-
|
84
|
+
semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
|
80
85
|
concat(builder.input(:id, :as => :enum_select))
|
81
86
|
end
|
82
87
|
end.should raise_error("id is not a ClassyEnum object. Make sure you've added 'classy_enum_attr :id' to your model")
|
83
88
|
end
|
84
89
|
|
85
|
-
it
|
90
|
+
it 'should raise an error if the attribute is not a ClassyEnum object and its value is nil' do
|
86
91
|
lambda do
|
87
|
-
|
92
|
+
semantic_form_for(Dog.new, :url => "/") do |builder|
|
88
93
|
concat(builder.input(:id, :as => :enum_select))
|
89
94
|
end
|
90
95
|
end.should raise_error("id is not a ClassyEnum object. Make sure you've added 'classy_enum_attr :id' to your model")
|
data/spec/spec_helper.rb
CHANGED
@@ -12,6 +12,10 @@ require 'classy_enum'
|
|
12
12
|
|
13
13
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
14
14
|
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.color_enabled = true
|
17
|
+
end
|
18
|
+
|
15
19
|
ActiveRecord::Schema.define(:version => 1) do
|
16
20
|
create_table :dogs, :force => true do |t|
|
17
21
|
t.string :breed
|
@@ -21,6 +25,13 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
21
25
|
t.string :other_breed
|
22
26
|
end
|
23
27
|
|
28
|
+
create_table :allow_blank_breed_dogs, :force => true do |t|
|
29
|
+
t.string :breed
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table :allow_nil_breed_dogs, :force => true do |t|
|
33
|
+
t.string :breed
|
34
|
+
end
|
24
35
|
end
|
25
36
|
|
26
37
|
class Breed < ClassyEnum::Base
|
@@ -31,6 +42,14 @@ class Dog < ActiveRecord::Base
|
|
31
42
|
classy_enum_attr :breed
|
32
43
|
end
|
33
44
|
|
45
|
+
class AllowBlankBreedDog < ActiveRecord::Base
|
46
|
+
classy_enum_attr :breed, :allow_blank => true
|
47
|
+
end
|
48
|
+
|
49
|
+
class AllowNilBreedDog < ActiveRecord::Base
|
50
|
+
classy_enum_attr :breed, :allow_nil => true
|
51
|
+
end
|
52
|
+
|
34
53
|
class OtherDog < ActiveRecord::Base
|
35
54
|
classy_enum_attr :other_breed, :enum => :breed
|
36
55
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: classy_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 61
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 1
|
10
|
+
version: 0.8.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Peter Brown
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-26 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -156,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements: []
|
157
157
|
|
158
158
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.6.
|
159
|
+
rubygems_version: 1.6.1
|
160
160
|
signing_key:
|
161
161
|
specification_version: 3
|
162
162
|
summary: A class based enumerator utility for Ruby on Rails
|