simple_enum 1.6.9 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/LICENSE +1 -1
- data/README.md +248 -0
- data/Rakefile +4 -21
- data/lib/simple_enum/accessors/accessor.rb +55 -0
- data/lib/simple_enum/accessors/ignore_accessor.rb +11 -0
- data/lib/simple_enum/accessors/whiny_accessor.rb +12 -0
- data/lib/simple_enum/accessors.rb +18 -0
- data/lib/simple_enum/attribute.rb +77 -0
- data/lib/simple_enum/enum.rb +37 -0
- data/lib/simple_enum/hasher.rb +26 -0
- data/lib/simple_enum/mongoid.rb +11 -15
- data/lib/simple_enum/translation.rb +17 -0
- data/lib/simple_enum/version.rb +2 -2
- data/lib/simple_enum.rb +19 -276
- data/simple_enum.gemspec +9 -9
- data/spec/simple_enum/accessors_spec.rb +212 -0
- data/spec/simple_enum/attribute_spec.rb +208 -0
- data/spec/simple_enum/enum_spec.rb +96 -0
- data/spec/simple_enum/hasher_spec.rb +63 -0
- data/spec/simple_enum/mongoid_spec.rb +44 -0
- data/spec/simple_enum/translation_spec.rb +66 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/active_record_support.rb +23 -0
- data/spec/support/i18n_support.rb +12 -0
- data/spec/support/model_support.rb +47 -0
- data/spec/support/mongoid_support.rb +21 -0
- metadata +50 -56
- data/README.rdoc +0 -293
- data/lib/simple_enum/enum_hash.rb +0 -64
- data/lib/simple_enum/validation.rb +0 -58
- data/locales/en.yml +0 -10
- data/test/array_conversions_test.rb +0 -21
- data/test/class_methods_test.rb +0 -114
- data/test/dirty_attributes_test.rb +0 -37
- data/test/enum_hash_test.rb +0 -73
- data/test/finders_test.rb +0 -45
- data/test/locales.yml +0 -25
- data/test/mongoid_test.rb +0 -66
- data/test/object_backed_test.rb +0 -61
- data/test/orm/active_record.rb +0 -114
- data/test/orm/common.rb +0 -23
- data/test/orm/mongoid.rb +0 -114
- data/test/poro_test.rb +0 -20
- data/test/prefixes_test.rb +0 -36
- data/test/simple_enum_test.rb +0 -314
- data/test/test_helper.rb +0 -40
- data/test/without_shortcuts_test.rb +0 -39
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Westermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,70 +16,70 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 4.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 10.1.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 10.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: activerecord
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 4.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 4.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: mongoid
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 4.0.0.beta1
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 4.0.0.beta1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '2.
|
75
|
+
version: '2.14'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '2.
|
82
|
+
version: '2.14'
|
83
83
|
description: Provides enum-like fields for ActiveRecord, ActiveModel and Mongoid models.
|
84
84
|
email:
|
85
85
|
- lukas.westermann@gmail.com
|
@@ -90,31 +90,31 @@ files:
|
|
90
90
|
- ".gitignore"
|
91
91
|
- Gemfile
|
92
92
|
- LICENSE
|
93
|
-
- README.
|
93
|
+
- README.md
|
94
94
|
- Rakefile
|
95
95
|
- lib/simple_enum.rb
|
96
|
-
- lib/simple_enum/
|
96
|
+
- lib/simple_enum/accessors.rb
|
97
|
+
- lib/simple_enum/accessors/accessor.rb
|
98
|
+
- lib/simple_enum/accessors/ignore_accessor.rb
|
99
|
+
- lib/simple_enum/accessors/whiny_accessor.rb
|
100
|
+
- lib/simple_enum/attribute.rb
|
101
|
+
- lib/simple_enum/enum.rb
|
102
|
+
- lib/simple_enum/hasher.rb
|
97
103
|
- lib/simple_enum/mongoid.rb
|
98
|
-
- lib/simple_enum/
|
104
|
+
- lib/simple_enum/translation.rb
|
99
105
|
- lib/simple_enum/version.rb
|
100
|
-
- locales/en.yml
|
101
106
|
- simple_enum.gemspec
|
102
|
-
-
|
103
|
-
-
|
104
|
-
-
|
105
|
-
-
|
106
|
-
-
|
107
|
-
-
|
108
|
-
-
|
109
|
-
-
|
110
|
-
-
|
111
|
-
-
|
112
|
-
-
|
113
|
-
- test/poro_test.rb
|
114
|
-
- test/prefixes_test.rb
|
115
|
-
- test/simple_enum_test.rb
|
116
|
-
- test/test_helper.rb
|
117
|
-
- test/without_shortcuts_test.rb
|
107
|
+
- spec/simple_enum/accessors_spec.rb
|
108
|
+
- spec/simple_enum/attribute_spec.rb
|
109
|
+
- spec/simple_enum/enum_spec.rb
|
110
|
+
- spec/simple_enum/hasher_spec.rb
|
111
|
+
- spec/simple_enum/mongoid_spec.rb
|
112
|
+
- spec/simple_enum/translation_spec.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/support/active_record_support.rb
|
115
|
+
- spec/support/i18n_support.rb
|
116
|
+
- spec/support/model_support.rb
|
117
|
+
- spec/support/mongoid_support.rb
|
118
118
|
homepage: http://lwe.github.com/simple_enum/
|
119
119
|
licenses:
|
120
120
|
- MIT
|
@@ -127,12 +127,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
127
127
|
requirements:
|
128
128
|
- - ">="
|
129
129
|
- !ruby/object:Gem::Version
|
130
|
-
version: 1.
|
130
|
+
version: 1.9.3
|
131
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
132
|
requirements:
|
133
133
|
- - ">="
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
135
|
+
version: 2.0.0
|
136
136
|
requirements: []
|
137
137
|
rubyforge_project:
|
138
138
|
rubygems_version: 2.2.0
|
@@ -140,20 +140,14 @@ signing_key:
|
|
140
140
|
specification_version: 4
|
141
141
|
summary: Simple enum-like field support for models.
|
142
142
|
test_files:
|
143
|
-
-
|
144
|
-
-
|
145
|
-
-
|
146
|
-
-
|
147
|
-
-
|
148
|
-
-
|
149
|
-
-
|
150
|
-
-
|
151
|
-
-
|
152
|
-
-
|
153
|
-
-
|
154
|
-
- test/orm/mongoid.rb
|
155
|
-
- test/poro_test.rb
|
156
|
-
- test/prefixes_test.rb
|
157
|
-
- test/simple_enum_test.rb
|
158
|
-
- test/test_helper.rb
|
159
|
-
- test/without_shortcuts_test.rb
|
143
|
+
- spec/simple_enum/accessors_spec.rb
|
144
|
+
- spec/simple_enum/attribute_spec.rb
|
145
|
+
- spec/simple_enum/enum_spec.rb
|
146
|
+
- spec/simple_enum/hasher_spec.rb
|
147
|
+
- spec/simple_enum/mongoid_spec.rb
|
148
|
+
- spec/simple_enum/translation_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/support/active_record_support.rb
|
151
|
+
- spec/support/i18n_support.rb
|
152
|
+
- spec/support/model_support.rb
|
153
|
+
- spec/support/mongoid_support.rb
|
data/README.rdoc
DELETED
@@ -1,293 +0,0 @@
|
|
1
|
-
= SimpleEnum - unobtrusive enum-like fields for ActiveRecord {<img src="https://secure.travis-ci.org/lwe/simple_enum.png" />}[http://travis-ci.org/lwe/simple_enum]
|
2
|
-
|
3
|
-
A Rails plugin which brings easy-to-use enum-like functionality to
|
4
|
-
ActiveRecord and Mongoid models (now compatible with rails 3.1, ruby 1.9 and jruby).
|
5
|
-
|
6
|
-
Since version 1.4, simple_enum is no longer compatible with activerecord 2.x, use
|
7
|
-
version 1.3.2 instead: <https://github.com/lwe/simple_enum/tree/v1.3.2>.
|
8
|
-
|
9
|
-
*Note*: a recent search on github for `enum` turned out, that there are many, many similar solutions.
|
10
|
-
|
11
|
-
== ActiveRecord Quick start
|
12
|
-
|
13
|
-
Add this to a model:
|
14
|
-
|
15
|
-
class User < ActiveRecord::Base
|
16
|
-
as_enum :gender, :female => 1, :male => 0
|
17
|
-
end
|
18
|
-
|
19
|
-
Then create the required `gender_cd` column using migrations:
|
20
|
-
|
21
|
-
class AddGenderColumnToUser < ActiveRecord::Migration
|
22
|
-
def self.up
|
23
|
-
add_column :users, :gender_cd, :integer
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.down
|
27
|
-
remove_column :users, :gender_cd
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
== Mongoid Quick start
|
32
|
-
|
33
|
-
Add this to an initializer
|
34
|
-
|
35
|
-
# load mongoid support
|
36
|
-
require 'simple_enum/mongoid'
|
37
|
-
|
38
|
-
Add this to a model:
|
39
|
-
|
40
|
-
class User
|
41
|
-
include Mongoid::Document
|
42
|
-
include SimpleEnum::Mongoid
|
43
|
-
|
44
|
-
as_enum :gender, :female => 1, :male => 0
|
45
|
-
end
|
46
|
-
|
47
|
-
== Working with enums
|
48
|
-
|
49
|
-
*Done*. Now it's possible to pull some neat tricks on the new column, yet
|
50
|
-
the original db column (+gender_cd+) is still intact and not touched by
|
51
|
-
any fancy metaclass or similar.
|
52
|
-
|
53
|
-
jane = User.new
|
54
|
-
jane.gender = :female
|
55
|
-
jane.female? # => true
|
56
|
-
jane.male? # => false
|
57
|
-
jane.gender # => :female
|
58
|
-
jane.gender_cd # => 1
|
59
|
-
|
60
|
-
Easily switch to another value using the bang methods.
|
61
|
-
|
62
|
-
joe = User.new
|
63
|
-
joe.male! # => :male
|
64
|
-
joe.gender # => :male
|
65
|
-
joe.gender_cd # => 0
|
66
|
-
|
67
|
-
There are even some neat tricks at class level, which might be
|
68
|
-
useful when creating queries, displaying option elements or similar:
|
69
|
-
|
70
|
-
User.genders # => { :male => 0, :female => 1 }
|
71
|
-
User.genders(:male) # => 0, same as User.male
|
72
|
-
User.female # => 1
|
73
|
-
User.genders.female # => 1, same as User.female or User.genders(:female)
|
74
|
-
|
75
|
-
== Wait, there's more!
|
76
|
-
* Too tired of always adding the integer values? Try:
|
77
|
-
|
78
|
-
class User < ActiveRecord::Base
|
79
|
-
as_enum :status, [:deleted, :active, :disabled] # translates to :deleted => 0, :active => 1, :disabled => 2
|
80
|
-
end
|
81
|
-
|
82
|
-
*Disclaimer*: if you _ever_ decide to reorder this array, beaware that any previous mapping is lost. So it's recommended
|
83
|
-
to create mappings (that might change) using hashes instead of arrays. For stuff like gender it might be probably perfectly
|
84
|
-
fine to use arrays though.
|
85
|
-
* You can use string values instead of integer values if your database column has the type +string+ or +text+:
|
86
|
-
|
87
|
-
class User < ActiveRecord::Base
|
88
|
-
as_enum :status, [:deleted, :active, :disabled], :strings => true
|
89
|
-
end
|
90
|
-
|
91
|
-
User.create!(status: :active) #=> #<User id: 1, status_cd: "active">
|
92
|
-
* Want to use `SimpleEnum` in an ActiveModel, or other class, just do:
|
93
|
-
|
94
|
-
class MyModel
|
95
|
-
include SimpleEnum
|
96
|
-
attr_accessor :gender_cd
|
97
|
-
as_enum :gender, [:male, :female]
|
98
|
-
end
|
99
|
-
|
100
|
-
* Maybe you've columns named differently than the proposed <tt>{column}_cd</tt> naming scheme, feel free to use any column name
|
101
|
-
by providing an option:
|
102
|
-
|
103
|
-
class User < ActiveRecord::Base
|
104
|
-
as_enum :gender, [:male, :female], :column => 'sex'
|
105
|
-
end
|
106
|
-
|
107
|
-
It's not allowed to use the same column name as the enum name, this has been deprecated since 1.4.x and will be
|
108
|
-
removed in 1.6.x.
|
109
|
-
* Want support for ActiveRecords dirty attributes, provide <tt>:dirty => true</tt> as option, which automatically adds both
|
110
|
-
the <tt>{enum}_changed?</tt> and <tt>{enum}_was</tt> methods, which delegate to ActiveRecord.
|
111
|
-
|
112
|
-
class User < ActiveRecord::Base
|
113
|
-
as_enum :gender, [:male, :female], :dirty => true
|
114
|
-
end
|
115
|
-
|
116
|
-
@user = User.where(:gender_cd => User.male).first
|
117
|
-
@user.gender = :female
|
118
|
-
@user.gender_was
|
119
|
-
# => :male
|
120
|
-
|
121
|
-
* Need to provide custom options for the mongoid field, or skip the automatically generated field?
|
122
|
-
|
123
|
-
# skip field generation
|
124
|
-
field :gender_cd # <- create field manually (!)
|
125
|
-
as_enum :gender, [:male, :female], :field => false
|
126
|
-
|
127
|
-
# custom field options (directly passed to Mongoid::Document#field)
|
128
|
-
as_enum :gender, [:male, :female], :field => { :type => Integer, :default => 1 }
|
129
|
-
|
130
|
-
* It's possible to validate the internal enum values, just like any other ActiveRecord validation:
|
131
|
-
|
132
|
-
class User < ActiveRecord::Base
|
133
|
-
as_enum :gender, [:male, :female]
|
134
|
-
validates :gender, :as_enum => true
|
135
|
-
# OR validates_as_enum :gender
|
136
|
-
end
|
137
|
-
|
138
|
-
All common options like <tt>:if</tt>, <tt>:unless</tt>, <tt>:allow_nil</tt> and <tt>:message</tt> are supported, because it just works within
|
139
|
-
the standard <tt>validates_each</tt>-loop. This validation method does not check the value of <tt>user.gender</tt>, but
|
140
|
-
instead the value of <tt>@user.gender_cd</tt>.
|
141
|
-
* If the shortcut methods (like <tt><symbol>?</tt>, <tt><symbol>!</tt> or <tt>Klass.<symbol></tt>) conflict with something in your class, it's possible to
|
142
|
-
define a prefix:
|
143
|
-
|
144
|
-
class User < ActiveRecord::Base
|
145
|
-
as_enum :gender, [:male, :female], :prefix => true
|
146
|
-
end
|
147
|
-
|
148
|
-
jane = User.new :gender => :female
|
149
|
-
jane.gender_female? # => true
|
150
|
-
User.gender_female # => 1, this also works on the class methods
|
151
|
-
|
152
|
-
The <tt>:prefix</tt> option not only takes a boolean value as an argument, but instead can also be supplied a custom
|
153
|
-
prefix (i.e. any string or symbol), so with <tt>:prefix => 'foo'</tt> all shortcut methods would look like: <tt>foo_<symbol>...</tt>
|
154
|
-
*Note*: if the <tt>:slim => true</tt> is defined, this option has no effect whatsoever (because no shortcut methods are generated).
|
155
|
-
* Sometimes it might be useful to disable the generation of the shortcut methods (<tt><symbol>?</tt>, <tt><symbol>!</tt> and <tt>Klass.<symbol></tt>),
|
156
|
-
to do so just add the option <tt>:slim => true</tt>:
|
157
|
-
|
158
|
-
class User < ActiveRecord::Base
|
159
|
-
as_enum :gender, [:male, :female], :slim => true
|
160
|
-
end
|
161
|
-
|
162
|
-
jane = User.new :gender => :female
|
163
|
-
jane.female? # => throws NoMethodError: undefined method `female?'
|
164
|
-
User.male # => throws NoMethodError: undefined method `male'
|
165
|
-
|
166
|
-
Yet the setter and getter for <tt>gender</tt>, as well as the <tt>User.genders</tt> methods are still available, only all shortcut
|
167
|
-
methods for each of the enumeration values are not generated.
|
168
|
-
|
169
|
-
It's also possible to set <tt>:slim => :class</tt> which only disables the generation of any class-level shortcut method, because those
|
170
|
-
are also available via the enhanced enumeration hash:
|
171
|
-
|
172
|
-
class Message < ActiveRecord::Base
|
173
|
-
as_enum :status, { :unread => 0, :read => 1, :archived => 99 }, :slim => :class
|
174
|
-
end
|
175
|
-
|
176
|
-
msg = Message.new :body => 'Hello World!', status_cd => 0
|
177
|
-
msg.read? # => false; shortuct methods on instance are still enabled
|
178
|
-
msg.status # => :unread
|
179
|
-
Message.unread # => throws NoMethodError: undefined method `unread`
|
180
|
-
Message.statuses.unread # => 0
|
181
|
-
Message.statuses.unread(true) # => :unread
|
182
|
-
|
183
|
-
# or useful for IN queries
|
184
|
-
Messages.statuses(:unread, :read) # => [0, 1]
|
185
|
-
|
186
|
-
* As a default an <tt>ArgumentError</tt> is raised if the user tries to set the field to an invalid enumeration value, to change this
|
187
|
-
behaviour use the <tt>:whiny</tt> option:
|
188
|
-
|
189
|
-
class User < ActiveRecord::Base
|
190
|
-
as_enum :gender, [:male, :female], :whiny => false
|
191
|
-
end
|
192
|
-
|
193
|
-
* To make it easier to create dropdowns with values use:
|
194
|
-
|
195
|
-
<%= select(:user, :gender, User.genders.keys) %>
|
196
|
-
|
197
|
-
* Need translated keys et al in your forms? SimpleEnum provides a <tt><enum>_for_select</tt> method:
|
198
|
-
|
199
|
-
# on the gender field
|
200
|
-
<%= select("user", "gender", User.genders_for_select) %>
|
201
|
-
|
202
|
-
# or on the '_cd' field
|
203
|
-
<%= select("user", "gender_cd", User.genders_for_select(:value))
|
204
|
-
|
205
|
-
Translations need to be stored like:
|
206
|
-
|
207
|
-
de:
|
208
|
-
activerecord:
|
209
|
-
enums:
|
210
|
-
user: # the Model, as User.class.name.underscore
|
211
|
-
genders: # pluralized version of :gender
|
212
|
-
male: männlich
|
213
|
-
female: weiblich
|
214
|
-
|
215
|
-
* To define any option globally, like setting <tt>:whiny</tt> to +false+, or globally enable <tt>:prefix</tt>; all default options
|
216
|
-
are stored in <tt>SimpleEnum.default_options</tt>, this hash can be easily changed in your initializers or wherever:
|
217
|
-
|
218
|
-
# e.g. setting :prefix => true (globally)
|
219
|
-
SimpleEnum.default_options[:prefix] = true
|
220
|
-
|
221
|
-
== Best practices
|
222
|
-
|
223
|
-
Do not use the same name for the enum as for the column, note that this mode of use is
|
224
|
-
deprecated since version 1.4.1 and raises an ArgumentError starting from version 1.6.0:
|
225
|
-
|
226
|
-
# BAD: raises ArgumentError
|
227
|
-
as_enum :status, [:active, :inactive, :archived], :column => "status"
|
228
|
-
|
229
|
-
# GOOD
|
230
|
-
as_enum :project_status, [:active, :inactive, :archived], :column => "status"
|
231
|
-
|
232
|
-
Do not use states named after existing, or well known method names, like `new` or `create`, e.g.
|
233
|
-
|
234
|
-
# BAD, conflicts with Rails ActiveRecord Methods (!)
|
235
|
-
as_enum :handle, [:new, :create, :update]
|
236
|
-
|
237
|
-
# BETTER, prefixes all methods
|
238
|
-
as_enum :handle, [:new, :create, :update], :prefix => true
|
239
|
-
|
240
|
-
Searching for certain values by using the finder methods:
|
241
|
-
|
242
|
-
User.where(:gender_cd => User.female)
|
243
|
-
|
244
|
-
Working with database backed values, now assuming that there exists a +genders+ table:
|
245
|
-
|
246
|
-
class Person < ActiveRecord::Base
|
247
|
-
as_enum :gender, Gender.all.map { |g| [g.name.to_sym, g.id] } # map to array of symbols
|
248
|
-
end
|
249
|
-
|
250
|
-
Working with object backed values, the only requirement to enable this is that <em>a)</em> either a field name +name+ exists
|
251
|
-
or <em>b)</em> a custom method to convert an object to a symbolized form named +to_enum_sym+ (for general uses overriding
|
252
|
-
+to_enum+ is perfectly fine) exists:
|
253
|
-
|
254
|
-
class Status < ActiveRecord::Base
|
255
|
-
# this has a column named :name
|
256
|
-
STATUSES = self.order(:name)
|
257
|
-
end
|
258
|
-
|
259
|
-
class BankTransaction < ActiveRecord::Base
|
260
|
-
as_enum :status, Status::STATUSES
|
261
|
-
end
|
262
|
-
|
263
|
-
# what happens now? the id's of Status now serve as enumeration key and the
|
264
|
-
# Status object as the value so...
|
265
|
-
t = BankTransaction.new
|
266
|
-
t.pending!
|
267
|
-
t.status # => #<Status id: 1, name: "pending">
|
268
|
-
|
269
|
-
# and it's also possible to access the objects/values using:
|
270
|
-
BankTransaction.statuses(:pending) # => 1, access by symbol (not) the object!
|
271
|
-
BankTransaction.statuses.pending # => 1
|
272
|
-
BankTransaction.statuses.pending(true) # => #<Status id: 1, name: "pending">
|
273
|
-
|
274
|
-
== Known issues/Open items
|
275
|
-
|
276
|
-
* Maybe the <tt>:whiny</tt> option should default to <tt>false</tt>, so that generally no exceptions are thrown if a user fakes a request?
|
277
|
-
* Convert to RSpec and clean up tests
|
278
|
-
* Make `:slim => true` the default option...?
|
279
|
-
|
280
|
-
== Contributors
|
281
|
-
|
282
|
-
* @dmitry - bugfixes and other improvements
|
283
|
-
* @tarsolya - implemented all the ruby 1.9 and rails 3 goodness!
|
284
|
-
* @dbalatero - rails 2.3.5 bugfix & validator fixes
|
285
|
-
* @johnthethird - feature for <tt>_for_select</tt> to return the values
|
286
|
-
* @sinsiliux - ruby 1.9 fixes and removed AR dependency
|
287
|
-
* @sled - mongoid support
|
288
|
-
* @abrom - <tt>find_by_...</tt> method
|
289
|
-
* @mhuggins - translations fixes
|
290
|
-
* and all others: https://github.com/lwe/simple_enum/graphs/contributors thanks
|
291
|
-
|
292
|
-
== Licence & Copyright
|
293
|
-
Copyright (c) 2011 by Lukas Westermann, Licenced under MIT Licence (see LICENCE file)
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module SimpleEnum
|
2
|
-
|
3
|
-
# Internal hash class, used to handle the enumerations et al.
|
4
|
-
# Works like to original +Hash+ class, but with some added value,
|
5
|
-
# like access to
|
6
|
-
#
|
7
|
-
class EnumHash < ::ActiveSupport::OrderedHash
|
8
|
-
|
9
|
-
# Converts an entity to a symbol, uses to_enum_sym, if possible.
|
10
|
-
def self.symbolize(sym)
|
11
|
-
return sym.to_enum_sym if sym.respond_to?(:to_enum_sym)
|
12
|
-
return sym.to_sym if sym.respond_to?(:to_sym)
|
13
|
-
return sym.name.to_s.parameterize('_').to_sym if sym.respond_to?(:name)
|
14
|
-
sym.to_param.to_sym if sym.present? && sym.respond_to?(:to_param)
|
15
|
-
sym unless sym.blank?
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(args = [], strings = false)
|
19
|
-
super()
|
20
|
-
|
21
|
-
@reverse_sym_lookup = {}
|
22
|
-
@sym_value_lookup = {}
|
23
|
-
|
24
|
-
if args.is_a?(Hash)
|
25
|
-
args.each { |k,v| set_value_for_reverse_lookup(k, v) }
|
26
|
-
else
|
27
|
-
ary = args.send(args.respond_to?(:enum_with_index) ? :enum_with_index : :each_with_index).to_a unless args.first.respond_to?(:map)
|
28
|
-
ary = args.map { |e| [e, e.id] } if args.first.respond_to?(:map) && !args.first.is_a?(Array)
|
29
|
-
ary ||= args
|
30
|
-
ary.each { |e| set_value_for_reverse_lookup(e[0], strings ? e[0].to_s : e[1]) }
|
31
|
-
end
|
32
|
-
|
33
|
-
@stringified_keys = keys.map(&:to_s)
|
34
|
-
|
35
|
-
freeze
|
36
|
-
end
|
37
|
-
|
38
|
-
def contains?(value)
|
39
|
-
@stringified_keys.include?(value.to_s) || values.include?(value)
|
40
|
-
end
|
41
|
-
|
42
|
-
def default(k = nil)
|
43
|
-
@sym_value_lookup[EnumHash.symbolize(k)] if k
|
44
|
-
end
|
45
|
-
|
46
|
-
def method_missing(symbol, *args)
|
47
|
-
sym = EnumHash.symbolize(symbol)
|
48
|
-
if @sym_value_lookup.has_key?(sym)
|
49
|
-
return @reverse_sym_lookup[sym] if args.first
|
50
|
-
self[symbol]
|
51
|
-
else
|
52
|
-
super
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
def set_value_for_reverse_lookup(key, value)
|
58
|
-
sym = EnumHash.symbolize(key)
|
59
|
-
self[key] = value
|
60
|
-
@reverse_sym_lookup[sym] = key
|
61
|
-
@sym_value_lookup[sym] = value
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module ActiveModel
|
2
|
-
module Validations
|
3
|
-
class AsEnumValidator < ActiveModel::Validator
|
4
|
-
attr_reader :attributes
|
5
|
-
|
6
|
-
def initialize(options)
|
7
|
-
@attributes = Array.wrap(options.delete(:attributes))
|
8
|
-
raise ":attributes cannot be blank" if @attributes.empty?
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def setup(klass)
|
13
|
-
@klass = klass
|
14
|
-
end
|
15
|
-
|
16
|
-
def validate(record)
|
17
|
-
attributes.each do |attribute|
|
18
|
-
enum_def = @klass.enum_definitions[attribute]
|
19
|
-
raw_value = record.send(enum_def[:column])
|
20
|
-
|
21
|
-
raw_value = raw_value.to_s if enum_def[:options][:strings] && raw_value
|
22
|
-
|
23
|
-
next if (raw_value.nil? && options[:allow_nil]) || (raw_value.blank? && options[:allow_blank])
|
24
|
-
|
25
|
-
unless @klass.send(enum_def[:name].to_s.pluralize).values.include?(raw_value)
|
26
|
-
record.errors.add(attribute, :invalid_enum, options)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module HelperMethods
|
33
|
-
# Validates an +as_enum+ field based on the value of it's column.
|
34
|
-
#
|
35
|
-
# Model:
|
36
|
-
# class User < ActiveRecord::Base
|
37
|
-
# as_enum :gender, [ :male, :female ]
|
38
|
-
# validates_as_enum :gender
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# View:
|
42
|
-
# <%= select(:user, :gender, User.genders.keys) %>
|
43
|
-
#
|
44
|
-
# Configuration options:
|
45
|
-
# * <tt>:message</tt> - A custom error message (default: is <tt>[:activerecord, :errors, :messages, :invalid_enum]</tt>).
|
46
|
-
# * <tt>:on</tt> - Specifies when this validation is active (default is always, other options <tt>:create</tt>, <tt>:update</tt>).
|
47
|
-
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
48
|
-
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
|
49
|
-
# method, proc or string should return or evaluate to a true or false value.
|
50
|
-
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
51
|
-
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
52
|
-
# method, proc or string should return or evaluate to a true or false value.
|
53
|
-
def validates_as_enum(*attr_names)
|
54
|
-
validates_with AsEnumValidator, _merge_attributes(attr_names)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/locales/en.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ArrayConversionsTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
reload_db :genders => true
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_conversion_to_enumartions
|
9
|
-
with_enum = named_dummy('DummyArrayTest1') do
|
10
|
-
as_enum :gender, Gender.all.map { |g| [g.name.to_sym, g.id] }
|
11
|
-
end
|
12
|
-
|
13
|
-
assert_equal @male.id, with_enum.male
|
14
|
-
assert_equal @female.id, with_enum.female
|
15
|
-
assert_equal @female.id, with_enum.genders(:female)
|
16
|
-
|
17
|
-
jane = with_enum.new :gender => :female
|
18
|
-
assert_equal :female, jane.gender
|
19
|
-
assert_equal @female.id, jane.gender_cd
|
20
|
-
end
|
21
|
-
end
|