active_enum 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +22 -7
- data/lib/active_enum/extensions.rb +6 -5
- data/lib/active_enum/formtastic.rb +12 -0
- data/lib/active_enum/version.rb +1 -1
- data/spec/active_enum/extensions_spec.rb +97 -90
- data/spec/active_enum/formtastic_spec.rb +59 -0
- data/spec/spec_helper.rb +7 -1
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Define enum classes in Rails and use them to enumerate ActiveRecord attributes. Brings together some ideas
|
4
4
|
of similar plugins that I liked and does it they way I prefer.
|
5
5
|
|
6
|
-
Enum values are stored in memory at the moment but I plan to add database and yaml.
|
6
|
+
Enum values are stored in memory at the moment but I plan to add database and yaml.
|
7
7
|
|
8
8
|
== Install
|
9
9
|
|
@@ -63,10 +63,11 @@ Skip the with option if the enum can be implied from the attribute
|
|
63
63
|
enumerate :sex
|
64
64
|
end
|
65
65
|
|
66
|
-
Define enum class implicitly
|
66
|
+
Define enum class implicitly from enumerate block. Enum class is namespaced by model class.
|
67
67
|
|
68
68
|
class User < ActiveRecord::Base
|
69
|
-
|
69
|
+
|
70
|
+
# defines User::Sex
|
70
71
|
enumerate :sex do
|
71
72
|
value :name => 'Male'
|
72
73
|
end
|
@@ -86,7 +87,7 @@ Access the enum values and the enum class using the attribute method with a symb
|
|
86
87
|
|
87
88
|
user.sex(:id) # => 1
|
88
89
|
user.sex(:name) # => 'Male'
|
89
|
-
user.sex(:enum) # => Sex
|
90
|
+
user.sex(:enum) # => Sex
|
90
91
|
|
91
92
|
You can check if the attribute value matches a particular enum value by passing the enum value as an argument to the question method
|
92
93
|
|
@@ -114,7 +115,7 @@ Define enum classes in bulk without class files, in an initializer file for exam
|
|
114
115
|
value :name => 'Female'
|
115
116
|
end
|
116
117
|
|
117
|
-
# defines Language
|
118
|
+
# defines Language
|
118
119
|
enum(:language) do
|
119
120
|
value :name => 'English'
|
120
121
|
value :name => 'German'
|
@@ -136,6 +137,22 @@ Giving you the familiar enum methods
|
|
136
137
|
User['Dave']
|
137
138
|
User.to_select
|
138
139
|
|
140
|
+
=== Formtastic
|
141
|
+
|
142
|
+
If you are a formtastic user you can use the extension for an enum input.
|
143
|
+
|
144
|
+
In an initialiser:
|
145
|
+
|
146
|
+
require 'active_enum/formtastic'
|
147
|
+
|
148
|
+
Then in a form you can use the :enum type for attribute inputs which are enumerated.
|
149
|
+
|
150
|
+
<% semantic_form_for(@person) do |f| %>
|
151
|
+
<%= f.input :sex, :as => :enum %>
|
152
|
+
<% end %>
|
153
|
+
|
154
|
+
This will output a select with the option values taken from the enum class for the attribute.
|
155
|
+
|
139
156
|
|
140
157
|
== TODO
|
141
158
|
* more docs
|
@@ -143,7 +160,5 @@ Giving you the familiar enum methods
|
|
143
160
|
* use custom method name for the enumerated attribute
|
144
161
|
* named_scopes
|
145
162
|
* question methods for enum names e.g. user.male?
|
146
|
-
* possibly allow string enum values to assigned to attributes
|
147
|
-
* add enum value class for instances if there is a need
|
148
163
|
|
149
164
|
Copyright (c) 2009 Adam Meehan, released under the MIT license
|
@@ -12,12 +12,12 @@ module ActiveEnum
|
|
12
12
|
module ClassMethods
|
13
13
|
|
14
14
|
# Declare an attribute to be enumerated by an enum class
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# class Person < ActiveRecord::Base
|
17
17
|
# enumerate :sex, :with => Sex
|
18
18
|
# enumerate :sex # implies a Sex enum class exists
|
19
19
|
#
|
20
|
-
# # Pass a block to create implicit enum class
|
20
|
+
# # Pass a block to create implicit enum class namespaced by model e.g. Person::Sex
|
21
21
|
# enumerate :sex do
|
22
22
|
# value :id => 1, :name => 'Male'
|
23
23
|
# end
|
@@ -30,9 +30,10 @@ module ActiveEnum
|
|
30
30
|
attributes.each do |attribute|
|
31
31
|
begin
|
32
32
|
if block_given?
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
enum_class_name = "#{self.name}::#{attribute.to_s.camelize}"
|
34
|
+
eval("class #{enum_class_name} < ActiveEnum::Base; end")
|
35
|
+
enum = enum_class_name.constantize
|
36
|
+
enum.class_eval &block
|
36
37
|
else
|
37
38
|
enum = options[:with] || attribute.to_s.classify.constantize
|
38
39
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActiveEnum
|
2
|
+
module Formtastic
|
3
|
+
|
4
|
+
def enum_input(method, options)
|
5
|
+
raise "Attribute '#{method}' has no enum class" unless enum = @object.class.enum_for(method)
|
6
|
+
select_input(method, options.merge(:collection => enum.to_select))
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Formtastic::SemanticFormBuilder.send :include, ActiveEnum::Formtastic
|
data/lib/active_enum/version.rb
CHANGED
@@ -12,12 +12,6 @@ class Accepted < ActiveEnum::Base
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe ActiveEnum::Extensions do
|
15
|
-
before do
|
16
|
-
Person.class_eval do
|
17
|
-
enumerate :sex, :with => Sex
|
18
|
-
end
|
19
|
-
@person = Person.new(:sex =>1)
|
20
|
-
end
|
21
15
|
|
22
16
|
it 'should add class :enumerate method to ActiveRecord' do
|
23
17
|
ActiveRecord::Base.should respond_to(:enumerate)
|
@@ -42,13 +36,13 @@ describe ActiveEnum::Extensions do
|
|
42
36
|
Person.enum_for(:sex).should == Sex
|
43
37
|
end
|
44
38
|
|
45
|
-
it 'should
|
39
|
+
it 'should create enum namespaced enum class from block' do
|
46
40
|
Person.class_eval do
|
47
41
|
enumerate :sex do
|
48
42
|
value :id => 1, :name => 'Male'
|
49
43
|
end
|
50
44
|
end
|
51
|
-
Person.enum_for(:sex).should ==
|
45
|
+
Person.enum_for(:sex).should == Person::Sex
|
52
46
|
end
|
53
47
|
|
54
48
|
it 'should raise error if implicit enumeration class cannot be found' do
|
@@ -57,121 +51,134 @@ describe ActiveEnum::Extensions do
|
|
57
51
|
end.should raise_error(ActiveEnum::EnumNotFound)
|
58
52
|
end
|
59
53
|
|
60
|
-
describe "attribute
|
61
|
-
|
62
|
-
|
54
|
+
describe "attribute" do
|
55
|
+
before(:all) do
|
56
|
+
reset_class Person do
|
57
|
+
enumerate :sex, :with => Sex
|
58
|
+
end
|
63
59
|
end
|
64
60
|
|
65
|
-
|
66
|
-
@person.
|
61
|
+
before do
|
62
|
+
@person = Person.new(:sex =>1)
|
67
63
|
end
|
68
64
|
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
describe "with value" do
|
66
|
+
it 'should return value with no arg' do
|
67
|
+
@person.sex.should == 1
|
68
|
+
end
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
70
|
+
it 'should return enum id for value' do
|
71
|
+
@person.sex(:id).should == 1
|
72
|
+
end
|
77
73
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
74
|
+
it 'should return enum name for value' do
|
75
|
+
@person.sex(:name).should == 'Male'
|
76
|
+
end
|
82
77
|
|
83
|
-
|
84
|
-
|
78
|
+
it 'should return enum class for attribute' do
|
79
|
+
@person.sex(:enum).should == Sex
|
80
|
+
end
|
85
81
|
end
|
86
82
|
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
describe "with nil value" do
|
84
|
+
before do
|
85
|
+
@person.sex = nil
|
86
|
+
end
|
90
87
|
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
it 'should return nil with no arg' do
|
89
|
+
@person.sex.should be_nil
|
90
|
+
end
|
94
91
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
92
|
+
it 'should return nil enum id' do
|
93
|
+
@person.sex(:id).should be_nil
|
94
|
+
end
|
99
95
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
96
|
+
it 'should return nil enum name' do
|
97
|
+
@person.sex(:name).should be_nil
|
98
|
+
end
|
104
99
|
|
105
|
-
|
106
|
-
|
100
|
+
it 'should return enum class for attribute' do
|
101
|
+
@person.sex(:enum).should == Sex
|
102
|
+
end
|
107
103
|
end
|
108
104
|
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
describe "with undefined value" do
|
106
|
+
before do
|
107
|
+
@person.sex = -1
|
108
|
+
end
|
112
109
|
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
it 'should return value with no arg' do
|
111
|
+
@person.sex.should == -1
|
112
|
+
end
|
116
113
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
114
|
+
it 'should return nil enum id' do
|
115
|
+
@person.sex(:id).should be_nil
|
116
|
+
end
|
121
117
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
118
|
+
it 'should return nil enum name' do
|
119
|
+
@person.sex(:name).should be_nil
|
120
|
+
end
|
126
121
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
@person.sex?.should be_false
|
122
|
+
it 'should return enum class for attribute' do
|
123
|
+
@person.sex(:enum).should == Sex
|
124
|
+
end
|
131
125
|
end
|
132
126
|
|
133
|
-
|
134
|
-
|
135
|
-
|
127
|
+
describe "question method" do
|
128
|
+
before do
|
129
|
+
@person.sex = 1
|
130
|
+
end
|
136
131
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
132
|
+
it 'should return normal value without arg' do
|
133
|
+
@person.sex?.should be_true
|
134
|
+
@person.sex = nil
|
135
|
+
@person.sex?.should be_false
|
136
|
+
end
|
141
137
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@person.sex?(:Female).should be_false
|
146
|
-
end
|
147
|
-
end
|
138
|
+
it 'should return true if string name matches for id value' do
|
139
|
+
@person.sex?("Male").should be_true
|
140
|
+
end
|
148
141
|
|
149
|
-
|
142
|
+
it 'should return true if symbol name matches for id value' do
|
143
|
+
@person.sex?(:male).should be_true
|
144
|
+
@person.sex?(:Male).should be_true
|
145
|
+
end
|
150
146
|
|
151
|
-
|
152
|
-
|
153
|
-
|
147
|
+
it 'should return false if name does not match for id value' do
|
148
|
+
@person.sex?("Female").should be_false
|
149
|
+
@person.sex?(:female).should be_false
|
150
|
+
@person.sex?(:Female).should be_false
|
151
|
+
end
|
154
152
|
end
|
155
153
|
|
156
|
-
|
157
|
-
@person.sex = :invalid
|
158
|
-
@person.sex.should == nil
|
159
|
-
end
|
154
|
+
describe "with value as enum name symbol" do
|
160
155
|
|
161
|
-
|
156
|
+
it 'should store id value when valid enum name' do
|
157
|
+
@person.sex = :female
|
158
|
+
@person.sex.should == 2
|
159
|
+
end
|
162
160
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
161
|
+
it 'should store nil value when invalid enum name' do
|
162
|
+
@person.sex = :invalid
|
163
|
+
@person.sex.should == nil
|
164
|
+
end
|
167
165
|
|
168
|
-
it 'should return text name value for attribute' do
|
169
|
-
@person.sex.should == 'Male'
|
170
166
|
end
|
171
167
|
|
172
|
-
|
173
|
-
|
168
|
+
describe "with value as enum name" do
|
169
|
+
before(:all) do
|
170
|
+
ActiveEnum.use_name_as_value = true
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should return text name value for attribute' do
|
174
|
+
@person.sex.should == 'Male'
|
175
|
+
end
|
176
|
+
|
177
|
+
after(:all) do
|
178
|
+
ActiveEnum.use_name_as_value = false
|
179
|
+
end
|
174
180
|
end
|
181
|
+
|
175
182
|
end
|
176
183
|
|
177
184
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'action_controller'
|
4
|
+
require 'action_view'
|
5
|
+
require 'formtastic'
|
6
|
+
require 'rspec_tag_matchers'
|
7
|
+
require 'active_enum/formtastic'
|
8
|
+
|
9
|
+
describe ActiveEnum::Formtastic do
|
10
|
+
include ActionView::Helpers::FormHelper
|
11
|
+
include ActionView::Helpers::FormTagHelper
|
12
|
+
include ActionView::Helpers::FormOptionsHelper
|
13
|
+
include ActionView::Helpers::UrlHelper
|
14
|
+
include ActionView::Helpers::TagHelper
|
15
|
+
include ActionView::Helpers::TextHelper
|
16
|
+
include ActionView::Helpers::ActiveRecordHelper
|
17
|
+
include ActionView::Helpers::RecordIdentificationHelper
|
18
|
+
include ActionView::Helpers::CaptureHelper
|
19
|
+
include ActionController::PolymorphicRoutes
|
20
|
+
include Formtastic::SemanticFormHelper
|
21
|
+
include RspecTagMatchers
|
22
|
+
|
23
|
+
attr_accessor :output_buffer
|
24
|
+
|
25
|
+
before do
|
26
|
+
reset_class Person do
|
27
|
+
enumerate :sex do
|
28
|
+
value :id => 1, :name => 'Male'
|
29
|
+
value :id => 2, :name => 'Female'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
@output_buffer = ''
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should use enum class for select option values for enum input type" do
|
37
|
+
semantic_form_for(Person.new) do |f|
|
38
|
+
concat f.input(:sex, :as => :enum)
|
39
|
+
end
|
40
|
+
output_buffer.should have_tag('select#person_sex') do |inner|
|
41
|
+
inner.should have_tag('//option[@value=1]', 'Male')
|
42
|
+
inner.should have_tag('//option[@value=2]', 'Female')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise error if attribute for enum input is not enumerated" do
|
47
|
+
lambda do
|
48
|
+
semantic_form_for(Person.new) {|f| f.input(:attending, :as => :enum) }
|
49
|
+
end.should raise_error "Attribute 'attending' has no enum class"
|
50
|
+
end
|
51
|
+
|
52
|
+
def protect_against_forgery?
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
def people_path
|
57
|
+
'/people'
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -17,7 +17,13 @@ require 'schema'
|
|
17
17
|
class Person < ActiveRecord::Base; end
|
18
18
|
|
19
19
|
module SpecHelper
|
20
|
-
|
20
|
+
def reset_class(klass, &block)
|
21
|
+
name = klass.name.to_sym
|
22
|
+
Object.send(:remove_const, name)
|
23
|
+
Object.const_set(name, Class.new(ActiveRecord::Base))
|
24
|
+
new_klass = Object.const_get(name)
|
25
|
+
new_klass.class_eval &block if block_given?
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
Spec::Runner.configure do |config|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Meehan
|
@@ -9,7 +9,7 @@ autorequire: active_enum
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-28 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -28,11 +28,13 @@ files:
|
|
28
28
|
- lib/active_enum/acts_as_enum.rb
|
29
29
|
- lib/active_enum/base.rb
|
30
30
|
- lib/active_enum/extensions.rb
|
31
|
+
- lib/active_enum/formtastic.rb
|
31
32
|
- lib/active_enum/version.rb
|
32
33
|
- lib/active_enum.rb
|
33
34
|
- spec/active_enum/acts_as_enum_spec.rb
|
34
35
|
- spec/active_enum/base_spec.rb
|
35
36
|
- spec/active_enum/extensions_spec.rb
|
37
|
+
- spec/active_enum/formtastic_spec.rb
|
36
38
|
- spec/active_enum_spec.rb
|
37
39
|
- spec/schema.rb
|
38
40
|
- spec/spec_helper.rb
|