simple_enum 1.6.9 → 2.3.2
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +9 -6
- data/LICENSE +1 -1
- data/README.md +331 -0
- data/Rakefile +9 -17
- data/lib/simple_enum/accessors/accessor.rb +61 -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 +28 -0
- data/lib/simple_enum/attribute.rb +109 -0
- data/lib/simple_enum/enum.rb +58 -0
- data/lib/simple_enum/hasher.rb +26 -0
- data/lib/simple_enum/mongoid.rb +16 -18
- data/lib/simple_enum/railtie.rb +17 -0
- data/lib/simple_enum/translation.rb +21 -0
- data/lib/simple_enum/version.rb +2 -2
- data/lib/simple_enum/view_helpers.rb +55 -0
- data/lib/simple_enum.rb +22 -278
- data/simple_enum.gemspec +9 -9
- data/spec/simple_enum/accessors_spec.rb +298 -0
- data/spec/simple_enum/attribute_spec.rb +272 -0
- data/spec/simple_enum/enum_spec.rb +136 -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 +70 -0
- data/spec/simple_enum/view_helpers_spec.rb +71 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/active_record_support.rb +27 -0
- data/spec/support/i18n_support.rb +12 -0
- data/spec/support/model_support.rb +47 -0
- data/spec/support/mongoid_support.rb +47 -0
- metadata +55 -57
- 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
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
|
data/test/class_methods_test.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ClassMethodsTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
reload_db
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_that_klass_genders_array_accessor_equal_to_attr_accessor
|
9
|
-
assert_equal 0, Dummy.genders(:male)
|
10
|
-
assert_equal Dummy.genders(:male), Dummy.genders[:male]
|
11
|
-
assert_nil Dummy.genders(:inexistent)
|
12
|
-
assert_nil Dummy.genders[:inexistent]
|
13
|
-
refute_nil Dummy.genders[:female]
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_inheritance_of_genders_to_subclasses
|
17
|
-
# issue#3
|
18
|
-
assert_equal({ :female => 1, :male => 0}, SpecificDummy.genders)
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_genders_reader_created
|
22
|
-
assert_equal [0, 1], Dummy.genders.values.sort
|
23
|
-
assert_equal %w{female male}, Dummy.genders.keys.map(&:to_s).sort
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_that_klass_genders_return_array_of_values
|
27
|
-
# usefuled for IN clauses
|
28
|
-
assert_equal [0, 1], Dummy.genders(:male, :female)
|
29
|
-
assert_equal [1, 0], Dummy.genders(:female, :male)
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_inverted_hash_returns_synonym_by_code
|
33
|
-
assert_equal :male, Dummy.genders.invert[0]
|
34
|
-
assert_equal :female, Dummy.genders.invert[1]
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_generation_of_value_shortcuts_on_class
|
38
|
-
g = Dummy.new
|
39
|
-
|
40
|
-
assert_equal 0, Dummy.male
|
41
|
-
assert_equal 1, Dummy.female
|
42
|
-
assert_equal 'alpha', Dummy.alpha
|
43
|
-
assert_respond_to Dummy, :male
|
44
|
-
assert_respond_to Dummy, :female
|
45
|
-
assert_respond_to Dummy, :beta
|
46
|
-
assert_respond_to Dummy, :foobar
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_that_no_klass_shortcuts_are_created_if_slim_true
|
50
|
-
with_slim = named_dummy('Dummy1') do
|
51
|
-
as_enum :gender, [:male, :female], :slim => true
|
52
|
-
end
|
53
|
-
|
54
|
-
assert !with_slim.respond_to?(:male)
|
55
|
-
assert !with_slim.respond_to?(:female)
|
56
|
-
assert_respond_to with_slim, :genders
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_that_no_klass_shortcuts_are_created_if_slim_class_though_instance_shortcuts_are
|
60
|
-
with_slim_class = named_dummy('Dummy2') do
|
61
|
-
as_enum :gender, [:male, :female], :slim => :class
|
62
|
-
end
|
63
|
-
|
64
|
-
jane = with_slim_class.new
|
65
|
-
|
66
|
-
assert_respond_to jane, :male!
|
67
|
-
assert_respond_to jane, :female!
|
68
|
-
assert !with_slim_class.respond_to?(:male)
|
69
|
-
assert !with_slim_class.respond_to?(:female)
|
70
|
-
assert_respond_to with_slim_class, :genders
|
71
|
-
assert_same 0, with_slim_class.genders.male
|
72
|
-
assert_same 1, with_slim_class.genders[:female]
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_that_klass_shortcuts_respect_prefix_true_and_are_prefixed_by_enum_cd
|
76
|
-
with_prefix = named_dummy('Dummy3') do
|
77
|
-
as_enum :gender, [:male, :female], :prefix => true
|
78
|
-
end
|
79
|
-
|
80
|
-
assert !with_prefix.respond_to?(:male)
|
81
|
-
assert !with_prefix.respond_to?(:female)
|
82
|
-
assert_respond_to with_prefix, :gender_male
|
83
|
-
assert_respond_to with_prefix, :gender_female
|
84
|
-
assert_equal 0, with_prefix.gender_male
|
85
|
-
assert_respond_to with_prefix, :genders
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_to_ensure_that_klass_shortcut_also_work_with_custom_prefixes
|
89
|
-
with_custom_prefix = named_dummy('Dummy4') do
|
90
|
-
as_enum :gender, [:male, :female], :prefix => :g
|
91
|
-
end
|
92
|
-
|
93
|
-
assert !with_custom_prefix.respond_to?(:male)
|
94
|
-
assert !with_custom_prefix.respond_to?(:female)
|
95
|
-
assert !with_custom_prefix.respond_to?(:gender_female)
|
96
|
-
assert_respond_to with_custom_prefix, :g_male
|
97
|
-
assert_respond_to with_custom_prefix, :g_female
|
98
|
-
assert_equal 1, with_custom_prefix.g_female
|
99
|
-
assert_respond_to with_custom_prefix, :genders
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_that_the_human_enum_name_method_returns_translated_humanized_values
|
103
|
-
assert_equal :male.to_s.humanize, Dummy.human_enum_name(:genders, :male)
|
104
|
-
assert_equal "Girl", Dummy.human_enum_name(:genders, :female)
|
105
|
-
assert_equal "Foo", Dummy.human_enum_name(:didums, :foo)
|
106
|
-
assert_equal "Foos", Dummy.human_enum_name(:didums, :foo, :count => 5)
|
107
|
-
end
|
108
|
-
|
109
|
-
def test_enum_for_select_value_class_method
|
110
|
-
for_select = Dummy.genders_for_select(:value)
|
111
|
-
assert_equal ["Male", 0], for_select.first
|
112
|
-
assert_equal ["Girl", 1], for_select.last
|
113
|
-
end
|
114
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
DirtyDummy = anonymous_dummy do
|
4
|
-
as_enum :gender, [:male, :female], :dirty => true
|
5
|
-
end
|
6
|
-
|
7
|
-
class DirtyAttributesTest < ActiveSupport::TestCase
|
8
|
-
def setup
|
9
|
-
reload_db
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_setting_using_changed_on_enum
|
13
|
-
jane = DirtyDummy.create!(:gender => :female)
|
14
|
-
assert_equal 1, jane.gender_cd
|
15
|
-
jane.gender = :male # operation? =)
|
16
|
-
assert_equal :male, jane.gender
|
17
|
-
assert_equal true, jane.gender_cd_changed?
|
18
|
-
assert_equal true, jane.gender_changed?
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_access_old_value_via_gender_was
|
22
|
-
john = DirtyDummy.create!(:gender => :male)
|
23
|
-
assert_equal 0, john.gender_cd
|
24
|
-
john.gender = :female
|
25
|
-
assert_equal :female, john.gender
|
26
|
-
assert_equal 0, john.gender_cd_was
|
27
|
-
assert_equal :male, john.gender_was
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_dirty_methods_are_disabled_by_default
|
31
|
-
no_dirty = Dummy.new
|
32
|
-
assert !no_dirty.respond_to?(:gender_was), "should not respond_to :gender_was"
|
33
|
-
assert !no_dirty.respond_to?(:gender_changed?), "should not respond_to :gender_changed?"
|
34
|
-
assert !no_dirty.respond_to?(:word_was), "should not respond_to :word_was"
|
35
|
-
assert !no_dirty.respond_to?(:word_changed?), "should not respond_to :word_changed?"
|
36
|
-
end
|
37
|
-
end
|
data/test/enum_hash_test.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'simple_enum/enum_hash'
|
3
|
-
|
4
|
-
class EnumHashTest < MiniTest::Unit::TestCase
|
5
|
-
|
6
|
-
def test_create_new_enumhash_instance_from_array_of_symbols
|
7
|
-
genders = SimpleEnum::EnumHash.new [:male, :female]
|
8
|
-
|
9
|
-
assert_same 0, genders[:male]
|
10
|
-
assert_same 1, genders[:female]
|
11
|
-
assert_same 0, genders.male
|
12
|
-
assert_same :female, genders.female(true)
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_create_new_enumhash_instance_from_hash
|
16
|
-
status = SimpleEnum::EnumHash.new :inactive => 0, :active => 1, :archived => 99
|
17
|
-
|
18
|
-
assert_same 0, status.inactive
|
19
|
-
assert_same 1, status[:active]
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_create_new_enumhash_instance_from_query_results
|
23
|
-
reload_db :genders => true
|
24
|
-
genders = SimpleEnum::EnumHash.new Gender.all
|
25
|
-
|
26
|
-
assert_same 0, genders[@male]
|
27
|
-
assert_same genders[@male], genders[:male]
|
28
|
-
assert_same 1, genders.female
|
29
|
-
assert_equal @male, genders.send(:male, true)
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_that_enumhash_keys_are_ordered
|
33
|
-
ordered = SimpleEnum::EnumHash.new [:alpha, :beta, :gamma, :delta, :epsilon, :zeta, :eta]
|
34
|
-
expected_keys = [:alpha, :beta, :gamma, :delta, :epsilon, :zeta, :eta]
|
35
|
-
assert_equal expected_keys, ordered.keys
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_valid_key_value_association_when_simple_array_is_merged_into_enumhash
|
39
|
-
a = [:a, :b, :c, :d]
|
40
|
-
h = SimpleEnum::EnumHash.new(a)
|
41
|
-
|
42
|
-
assert_same 0, h[:a]
|
43
|
-
assert_same 1, h[:b]
|
44
|
-
assert_same 2, h[:c]
|
45
|
-
assert_same 3, h[:d]
|
46
|
-
assert_equal [:a, :b, :c, :d], h.keys
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_that_an_already_correct_looking_array_is_converted_to_hash
|
50
|
-
a = [[:a, 5], [:b, 10]]
|
51
|
-
h = SimpleEnum::EnumHash.new(a)
|
52
|
-
|
53
|
-
assert_same 5, h[:a]
|
54
|
-
assert_same 10, h[:b]
|
55
|
-
assert_equal [:a, :b], h.keys
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_that_an_array_of_query_results_are_converted_to_result_ids
|
59
|
-
reload_db :genders => true # reload db
|
60
|
-
a = Gender.all
|
61
|
-
|
62
|
-
h = SimpleEnum::EnumHash.new(a)
|
63
|
-
|
64
|
-
assert_same 0, h[@male]
|
65
|
-
assert_same 1, h[@female]
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_strings_option
|
69
|
-
h = SimpleEnum::EnumHash.new([:male, :female], true)
|
70
|
-
assert_equal "male", h[:male]
|
71
|
-
assert_equal "female", h[:female]
|
72
|
-
end
|
73
|
-
end
|