power_enum 0.8.6 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.md → README.markdown} +315 -157
- data/lib/active_record/virtual_enumerations.rb +132 -48
- data/lib/power_enum/enumerated.rb +405 -0
- data/lib/power_enum/has_enumerated.rb +234 -0
- data/lib/power_enum.rb +18 -2
- metadata +7 -8
- data/examples/virtual_enumerations_sample.rb +0 -76
- data/lib/active_record/acts/enumerated.rb +0 -395
- data/lib/active_record/aggregations/has_enumerated.rb +0 -238
@@ -1,6 +1,6 @@
|
|
1
1
|
# Power Enum
|
2
2
|
|
3
|
-
https://github.com/albertosaurus/
|
3
|
+
https://github.com/albertosaurus/power_enum
|
4
4
|
|
5
5
|
Enumerations for Rails 3.X Done Right.
|
6
6
|
|
@@ -12,23 +12,36 @@ It is particularly suitable for scenarios where your Rails application is not th
|
|
12
12
|
when it's used for analytics or reporting.
|
13
13
|
|
14
14
|
Power Enum is a fork of the Rails 3 modernization made by the fine folks at Protocool
|
15
|
-
https://github.com/protocool/
|
15
|
+
https://github.com/protocool/enumerations_mixin to the original plugin by Trevor Squires. While many of the core ideas
|
16
16
|
remain, it has been reworked and a full test suite written to facilitate further development.
|
17
17
|
|
18
18
|
At it's most basic level, it allows you to say things along the lines of:
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
```ruby
|
21
|
+
# Create a provisional booking
|
22
|
+
booking = Booking.new( :status => BookingStatus[:provisional] )
|
23
|
+
# Set the booking status to 'confirmed'
|
24
|
+
booking.status = :confirmed
|
25
|
+
booking = Booking.create( :status => :rejected )
|
26
|
+
# And now...
|
27
|
+
booking.status == BookingStatus[:rejected] # evaluates to true
|
28
|
+
booking.status === :rejected # also evaluates to true
|
29
|
+
booking.status === [:rejected, :confirmed, :provisional] # and so does this
|
23
30
|
|
24
|
-
|
31
|
+
Booking.where( :status_id => BookingStatus[:provisional] )
|
25
32
|
|
26
|
-
|
27
|
-
|
28
|
-
Booking.with_status :provisional, :confirmed
|
33
|
+
BookingStatus.all.collect { |status|, [status.name, status.id] }
|
29
34
|
|
35
|
+
# built in scopes make life easier
|
36
|
+
Booking.with_status( :provisional, :confirmed )
|
37
|
+
```
|
30
38
|
See "How to use it" below for more information.
|
31
39
|
|
40
|
+
## Requirements
|
41
|
+
|
42
|
+
* Ruby 1.8.7, 1.9.2, 1.9.3, JRuby 1.6+
|
43
|
+
* Rails 3.0, 3.1, 3.2
|
44
|
+
|
32
45
|
## Installation
|
33
46
|
|
34
47
|
Add the gem to your Gemfile
|
@@ -87,55 +100,67 @@ from a pre-test Rake task.
|
|
87
100
|
|
88
101
|
If you're using Rails 3.0, your migration file will look something like this:
|
89
102
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
103
|
+
```ruby
|
104
|
+
class CreateEnumBookingStatus < ActiveRecord::Migration
|
105
|
+
|
106
|
+
def self.up
|
107
|
+
create_enum :booking_status
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.down
|
111
|
+
remove_enum :booking_status
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
```
|
101
116
|
|
102
117
|
If you're using Rails 3.1 or later, it will look something like this:
|
103
118
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
119
|
+
```ruby
|
120
|
+
class CreateEnumBookingStatus < ActiveRecord::Migration
|
121
|
+
|
122
|
+
def change
|
123
|
+
create_enum :booking_status
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
```
|
111
128
|
|
112
129
|
You can now customize it.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
create_enum :booking_status, :name_limit => 50
|
133
|
+
# The above is equivalent to saying
|
134
|
+
# create_table :booking_statuses do |t|
|
135
|
+
# t.string :name, :limit => 50, :null => false
|
136
|
+
# end
|
137
|
+
```
|
119
138
|
|
120
139
|
Now, when you create your Booking model, your migration should create a reference column for status id's and a foreign
|
121
140
|
key relationship to the booking\_statuses table.
|
122
|
-
|
123
|
-
create_table :bookings do |t|
|
124
|
-
t.integer :status_id
|
125
141
|
|
126
|
-
|
127
|
-
|
142
|
+
```ruby
|
143
|
+
create_table :bookings do |t|
|
144
|
+
t.integer :status_id
|
128
145
|
|
129
|
-
|
130
|
-
|
146
|
+
t.timestamps
|
147
|
+
end
|
148
|
+
|
149
|
+
# It's highly recommended to add a foreign key constraint here.
|
150
|
+
# Ideally, you would use a gem of some sort to handle this.
|
151
|
+
execute "ALTER TABLE bookings ADD 'bookings_bookings_status_id_fk'"\
|
152
|
+
" FOREIGN KEY (status_id) REFERENCES booking_statuses (id);"
|
153
|
+
```
|
131
154
|
|
132
155
|
It's easier to use the `references` method if you intend to stick to the default naming convention for reference columns.
|
133
156
|
|
134
|
-
|
135
|
-
|
157
|
+
```ruby
|
158
|
+
create_table :bookings do |t|
|
159
|
+
t.references :booking_status # Same as t.integer booking_status_id
|
136
160
|
|
137
|
-
|
138
|
-
|
161
|
+
t.timestamps
|
162
|
+
end
|
163
|
+
```
|
139
164
|
|
140
165
|
There are two methods added to Rails migrations:
|
141
166
|
|
@@ -154,47 +179,60 @@ You can also pass in a block that takes a table object as an argument, like `cre
|
|
154
179
|
|
155
180
|
Example:
|
156
181
|
|
157
|
-
|
182
|
+
```ruby
|
183
|
+
create_enum :booking_status
|
184
|
+
```
|
158
185
|
|
159
186
|
is the equivalent of
|
160
187
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
188
|
+
```ruby
|
189
|
+
create_table :booking_statuses do |t|
|
190
|
+
t.string :name, :null => false
|
191
|
+
end
|
192
|
+
add_index :booking_statuses, [:name], :unique => true
|
193
|
+
```
|
165
194
|
|
166
195
|
In a more complex case:
|
167
196
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
197
|
+
```ruby
|
198
|
+
create_enum :booking_status,
|
199
|
+
:name_column => :booking_name,
|
200
|
+
:name_limit => 50,
|
201
|
+
:description => true,
|
202
|
+
:desc_limit => 100,
|
203
|
+
:active => true,
|
204
|
+
:timestamps => true
|
205
|
+
```
|
174
206
|
|
175
207
|
is the equivalent of
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
create_table :booking_statuses do |t|
|
211
|
+
t.string :booking_name, :limit => 50, :null => false
|
212
|
+
t.string :description, :limit => 100
|
213
|
+
t.boolean :active, :null => false, :default => true
|
214
|
+
t.timestamps
|
215
|
+
end
|
216
|
+
add_index :booking_statuses, [:booking_name], :unique => true
|
217
|
+
```
|
184
218
|
|
185
219
|
You can also customize the creation process by using a block:
|
186
220
|
|
187
|
-
|
188
|
-
|
189
|
-
|
221
|
+
```ruby
|
222
|
+
create_enum :booking_status do |t|
|
223
|
+
t.boolean :first_booking, :null => false
|
224
|
+
end
|
225
|
+
```
|
190
226
|
|
191
227
|
is the equivalent of
|
192
228
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
229
|
+
```ruby
|
230
|
+
create_table :booking_statuses do |t|
|
231
|
+
t.string :name, :null => false
|
232
|
+
t.boolean :first_booking, :null => false
|
233
|
+
end
|
234
|
+
add_index :booking_statuses, [:name], :unique => true
|
235
|
+
```
|
198
236
|
|
199
237
|
Notice that a unique index is automatically created on the specified name column.
|
200
238
|
|
@@ -204,20 +242,29 @@ Drops the enum table. `enum_name` will be automatically pluralized.
|
|
204
242
|
|
205
243
|
Example:
|
206
244
|
|
207
|
-
|
245
|
+
```ruby
|
246
|
+
remove_enum :booking_status
|
247
|
+
```
|
208
248
|
|
209
249
|
is the equivalent of
|
210
|
-
|
211
|
-
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
drop_table :booking_statuses
|
253
|
+
```
|
212
254
|
|
213
255
|
### acts\_as\_enumerated
|
214
256
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
257
|
+
```ruby
|
258
|
+
class BookingStatus < ActiveRecord::Base
|
259
|
+
acts_as_enumerated :conditions => 'optional_sql_conditions',
|
260
|
+
:order => 'optional_sql_order_by',
|
261
|
+
:on_lookup_failure => :optional_class_method, #This also works: lambda{ |arg| some_custom_action }
|
262
|
+
:name_column => 'optional_name_column' #If required, may override the default name column
|
263
|
+
:alias_name => false #If set to false and have name_column set, will not
|
264
|
+
# alias :name to the name column attribute
|
265
|
+
# (version 0.9.0).
|
266
|
+
end
|
267
|
+
```
|
221
268
|
|
222
269
|
With that, your BookingStatus class will have the following methods defined:
|
223
270
|
|
@@ -270,11 +317,13 @@ to perform any updates.
|
|
270
317
|
|
271
318
|
Example:
|
272
319
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
320
|
+
```ruby
|
321
|
+
BookingStatus.update_enumerations_model do
|
322
|
+
BookingStatus.create :name => 'Foo',
|
323
|
+
:description => 'Bar',
|
324
|
+
:active => false
|
325
|
+
end
|
326
|
+
```
|
278
327
|
|
279
328
|
##### acts\_as\_enumerated? (since version 0.8.6)
|
280
329
|
|
@@ -296,16 +345,20 @@ Behavior depends on the type of `arg`.
|
|
296
345
|
|
297
346
|
Examples:
|
298
347
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
348
|
+
```ruby
|
349
|
+
BookingStatus[:foo] === :foo #Returns true
|
350
|
+
BookingStatus[:foo] === 'foo' #Returns true
|
351
|
+
BookingStatus[:foo] === :bar #Returns false
|
352
|
+
BookingStatus[:foo] === [:foo, :bar, :baz] #Returns true
|
353
|
+
BookingStatus[:foo] === nil #Returns false
|
354
|
+
```
|
304
355
|
|
305
356
|
You should note that defining an `:on_lookup_failure` method that raises an exception will cause `===` to also raise an
|
306
357
|
exception for any lookup failure of `BookingStatus[arg]`.
|
307
358
|
|
308
|
-
|
359
|
+
##### like?(arg)
|
360
|
+
|
361
|
+
Aliased to `===`
|
309
362
|
|
310
363
|
##### in?(*list)
|
311
364
|
|
@@ -313,16 +366,27 @@ Returns true if any element in the list returns true for `===(arg)`, false other
|
|
313
366
|
|
314
367
|
Example:
|
315
368
|
|
316
|
-
|
369
|
+
```ruby
|
370
|
+
BookingStatus[:foo].in? :foo, :bar, :baz #Returns true
|
371
|
+
```
|
372
|
+
|
373
|
+
##### to_s
|
374
|
+
|
375
|
+
Returns the string representation of the enum, i.e. the value in the `:name_column` attribute of the enumeration model.
|
317
376
|
|
318
377
|
##### name
|
319
378
|
|
320
|
-
|
379
|
+
By default, aliased to the string representation of the `:name_column` attribute. To avoid this, set the `alias_name`
|
380
|
+
option to `false`.
|
321
381
|
|
322
382
|
##### name\_sym
|
323
383
|
|
324
384
|
Returns the symbol representation of the name of the enum. `BookingStatus[:foo].name_sym` returns :foo.
|
325
385
|
|
386
|
+
##### to\_sym
|
387
|
+
|
388
|
+
Aliased to `name_sym` (Since version 0.9.0).
|
389
|
+
|
326
390
|
##### active?
|
327
391
|
|
328
392
|
Returns true if the instance is active, false otherwise. If it has an attribute 'active',
|
@@ -346,10 +410,12 @@ into the database.
|
|
346
410
|
|
347
411
|
Using the above example you would do the following:
|
348
412
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
413
|
+
```ruby
|
414
|
+
BookingStatus.enumeration_model_updates_permitted = true
|
415
|
+
['pending', 'confirmed', 'canceled'].each do | status_name |
|
416
|
+
BookingStatus.create( :name => status_name )
|
417
|
+
end
|
418
|
+
```
|
353
419
|
|
354
420
|
Note that a `:presence` and `:uniqueness` validation is automatically defined on each model for the name column.
|
355
421
|
|
@@ -359,14 +425,17 @@ First of all, note that you *could* specify the relationship to an `acts_as_enum
|
|
359
425
|
association. However, `has_enumerated` is preferable because you aren't really associated to the enumerated value, you
|
360
426
|
are *aggregating* it. As such, the `has_enumerated` macro behaves more like an aggregation than an association.
|
361
427
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
428
|
+
```ruby
|
429
|
+
class Booking < ActiveRecord::Base
|
430
|
+
has_enumerated :status,
|
431
|
+
:class_name => 'BookingStatus',
|
432
|
+
:foreign_key => 'status_id',
|
433
|
+
:on_lookup_failure => :optional_instance_method,
|
434
|
+
:permit_empty_name => true, #Setting this to true disables automatic conversion of empty strings to nil. Default is false.
|
435
|
+
:default => :unconfirmed, #Default value of the attribute.
|
436
|
+
:create_scope => false #Setting this to false disables the automatic creation of the 'with_status' scope.
|
437
|
+
end
|
438
|
+
```
|
370
439
|
|
371
440
|
By default, the foreign key is interpreted to be the name of your has\_enumerated field (in this case 'booking\_status')
|
372
441
|
plus '\_id'. Since we chose to make the column name 'status\_id' for the sake of brevity, we must explicitly designate
|
@@ -391,15 +460,21 @@ id directly.
|
|
391
460
|
|
392
461
|
example:
|
393
462
|
|
394
|
-
|
395
|
-
|
463
|
+
```ruby
|
464
|
+
mybooking.status = :confirmed
|
465
|
+
```
|
466
|
+
|
396
467
|
this is equivalent to:
|
397
468
|
|
398
|
-
|
469
|
+
```ruby
|
470
|
+
mybooking.status = 'confirmed'
|
471
|
+
```
|
399
472
|
|
400
473
|
or:
|
401
474
|
|
402
|
-
|
475
|
+
```ruby
|
476
|
+
mybooking.status = BookingStatus[:confirmed]
|
477
|
+
```
|
403
478
|
|
404
479
|
The `:on_lookup_failure` option in has\_enumerated is there because you may want to create an error handler for
|
405
480
|
situations where the argument passed to `status=(arg)` is invalid. By default, an invalid value will cause an
|
@@ -412,7 +487,9 @@ subsequent lookups, but the model will fail validation.
|
|
412
487
|
|
413
488
|
2) Specify an *instance* method to be called in the case of a lookup failure. The method signature is as follows:
|
414
489
|
|
415
|
-
|
490
|
+
```ruby
|
491
|
+
your_lookup_handler(operation, name, name_foreign_key, acts_enumerated_class_name, lookup_value)
|
492
|
+
```
|
416
493
|
|
417
494
|
The 'operation' arg will be either `:read` or `:write`. In the case of `:read` you are expected to return something or
|
418
495
|
raise an exception, while in the case of a `:write` you don't have to return anything.
|
@@ -424,9 +501,11 @@ failures for all has\_enumerated fields if you happen to have more than one defi
|
|
424
501
|
its first argument, with the rest of the arguments being identical to the signature of the lookup handler instance
|
425
502
|
method.
|
426
503
|
|
427
|
-
|
428
|
-
|
429
|
-
|
504
|
+
```ruby
|
505
|
+
:on_lookup_failure => lambda{ |record, op, attr, fk, cl_name, value|
|
506
|
+
# handle lookup failure
|
507
|
+
}
|
508
|
+
```
|
430
509
|
|
431
510
|
NOTE: A `nil` is always considered to be a valid value for `status=(arg)` since it's assumed you're trying to null out
|
432
511
|
the foreign key. The `:on_lookup_failure` will be bypassed.
|
@@ -436,12 +515,16 @@ the foreign key. The `:on_lookup_failure` will be bypassed.
|
|
436
515
|
Unless the `:create_scope` option is set to `false`, a scope is automatically created that takes a list of enums as
|
437
516
|
arguments. This allows us to say things like:
|
438
517
|
|
439
|
-
|
518
|
+
```ruby
|
519
|
+
Booking.with_status :confirmed, :received
|
520
|
+
```
|
440
521
|
|
441
522
|
Strings, symbols, ids, or enum instances are all valid arguments. For example, the following would be valid, though not
|
442
523
|
recommended for obvious reasons.
|
443
524
|
|
444
|
-
|
525
|
+
```ruby
|
526
|
+
Booking.with_status 1, 'confirmed', BookingStatus[:rejected]
|
527
|
+
```
|
445
528
|
|
446
529
|
As of version 0.5.5, it also aliases a pluralized version of the scope, i.e. `:with_statuses`
|
447
530
|
|
@@ -450,7 +533,9 @@ As of version 0.5.5, it also aliases a pluralized version of the scope, i.e. `:w
|
|
450
533
|
As of version 0.8.0, a scope for the inverse of `with_enumerated_attribute` is created, unless the `:create_scope`
|
451
534
|
option is set to `false`. As a result, this allows us to do things like
|
452
535
|
|
453
|
-
|
536
|
+
```ruby
|
537
|
+
Booking.exclude_status :received
|
538
|
+
```
|
454
539
|
|
455
540
|
This will give us all the Bookings where the status is a value other than `BookingStatus[:received]`.
|
456
541
|
|
@@ -473,15 +558,72 @@ Returns an array of attributes which are enumerated.
|
|
473
558
|
|
474
559
|
### ActiveRecord::VirtualEnumerations
|
475
560
|
|
476
|
-
In many instances, your `acts_as_enumerated` classes will do nothing more than just act as enumerated.
|
561
|
+
In many instances, your `acts_as_enumerated` classes will do nothing more than just act as enumerated. In that case,
|
562
|
+
you can use ActiveRecord::VirtualEnumerations to reduce that clutter.
|
563
|
+
|
564
|
+
Create a custom Rails initializer: Rails.root/config/initializers/virtual\_enumerations.rb
|
565
|
+
|
566
|
+
```ruby
|
567
|
+
ActiveRecord::VirtualEnumerations.define do |config|
|
568
|
+
|
569
|
+
# Define the enum class
|
570
|
+
config.define 'ClassName',
|
571
|
+
:table_name => 'table',
|
572
|
+
:extends => 'SuperclassName',
|
573
|
+
:conditions => ['something = ?', "value"],
|
574
|
+
:order => 'column ASC',
|
575
|
+
:on_lookup_failure => :enforce_strict,
|
576
|
+
:name_column => 'name_column',
|
577
|
+
:alias_name => false {
|
578
|
+
# This gets evaluated within the class scope of the enum class.
|
579
|
+
def to_s
|
580
|
+
"#{id} - #{name}"
|
581
|
+
end
|
582
|
+
}
|
583
|
+
|
584
|
+
end
|
585
|
+
```
|
586
|
+
|
587
|
+
Only the 'ClassName' argument is required. `:table_name` is used to define a custom table name while the `:extends`
|
588
|
+
option is used to set a custom superclass. Class names can be either camel-cased like ClassName or with
|
589
|
+
underscores, like class\_name. Strings and symbols are both fine.
|
590
|
+
|
591
|
+
If you need to fine-tune the definition of the enum class, you can optionally pass in a block, which will be
|
592
|
+
evaluated in the context of the enum class.
|
593
|
+
|
594
|
+
Example:
|
595
|
+
|
596
|
+
```ruby
|
597
|
+
config.define :color, :on_lookup_failure => :enforce_strict, do
|
598
|
+
def to_argb(alpha)
|
599
|
+
case self.to_sym
|
600
|
+
when :white
|
601
|
+
[alpha, 255, 255, 255]
|
602
|
+
when :red
|
603
|
+
[alpha, 255, 0, 0]
|
604
|
+
when :blue
|
605
|
+
[alpha, 0, 0, 255]
|
606
|
+
when :yellow
|
607
|
+
[alpha, 255, 255, 0]
|
608
|
+
when :black
|
609
|
+
[alpha, 0, 0, 0]
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
```
|
614
|
+
|
615
|
+
As a convenience, if multiple enums share the same configuration, you can pass all of them to config.define.
|
477
616
|
|
478
|
-
|
479
|
-
|
617
|
+
```ruby
|
618
|
+
config.define :booking_status, :connector_type, :color, :order => :name
|
619
|
+
```
|
480
620
|
|
481
|
-
|
482
|
-
accordingly.
|
621
|
+
STI is also supported:
|
483
622
|
|
484
|
-
|
623
|
+
```ruby
|
624
|
+
config.define :base_enum, :name_column => ;foo
|
625
|
+
config.define :booking_status, :connector_type, :color, :extends => :base_enum
|
626
|
+
```
|
485
627
|
|
486
628
|
### Testing (Since version 0.6.0)
|
487
629
|
|
@@ -491,62 +633,78 @@ A pair of custom RSpec matchers are included to streamline testing of enums and
|
|
491
633
|
|
492
634
|
This is used to test that a model acts as enumerated. Example:
|
493
635
|
|
494
|
-
|
495
|
-
|
496
|
-
|
636
|
+
```ruby
|
637
|
+
describe BookingStatus do
|
638
|
+
it { should act_as_enumerated }
|
639
|
+
end
|
640
|
+
```
|
497
641
|
|
498
642
|
This also works:
|
499
643
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
644
|
+
```ruby
|
645
|
+
describe BookingStatus do
|
646
|
+
it "should act as enumerated" do
|
647
|
+
BookingStatus.should act_as_enumerated
|
648
|
+
end
|
649
|
+
end
|
650
|
+
```
|
505
651
|
|
506
652
|
You can use the `with_items` chained matcher to test that each enum is properly seeded:
|
507
653
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
654
|
+
```ruby
|
655
|
+
describe BookingStatus do
|
656
|
+
it {
|
657
|
+
should act_as_enumerated.with_items(:confirmed, :received, :rejected)
|
658
|
+
}
|
659
|
+
end
|
660
|
+
```
|
513
661
|
|
514
662
|
You can also pass in hashes if you want to be thorough and test out all the attributes of each enum. If
|
515
663
|
you do this, you must pass in the `:name` attribute in each hash
|
516
664
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
}
|
523
|
-
|
665
|
+
```ruby
|
666
|
+
describe BookingStatus do
|
667
|
+
it {
|
668
|
+
should act_as_enumerated.with_items(
|
669
|
+
{ :name => 'confirmed', :description => "Processed and confirmed" },
|
670
|
+
{ :name => 'received', :description => "Pending confirmation" },
|
671
|
+
{ :name => 'rejected', :description => "Rejected due to internal rules" }
|
672
|
+
)
|
673
|
+
}
|
674
|
+
end
|
675
|
+
```
|
524
676
|
|
525
677
|
#### have\_enumerated
|
526
678
|
|
527
679
|
This is used to test that a model has enumerated the given attribute:
|
528
680
|
|
529
|
-
|
530
|
-
|
531
|
-
|
681
|
+
```ruby
|
682
|
+
describe Booking do
|
683
|
+
it { should have_enumerated(:status) }
|
684
|
+
end
|
685
|
+
```
|
532
686
|
|
533
687
|
This is also valid:
|
534
688
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
689
|
+
```ruby
|
690
|
+
describe Booking do
|
691
|
+
it "Should have enumerated the status attribute" do
|
692
|
+
Booking.should have_enumerated(:status)
|
693
|
+
end
|
694
|
+
end
|
695
|
+
```
|
540
696
|
|
541
697
|
#### match\_enum (Since version 0.8.6)
|
542
698
|
|
543
699
|
Tests if an enum instance matches the given value, which may be a symbol, id, string, or enum instance:
|
544
700
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
701
|
+
```ruby
|
702
|
+
describe Booking do
|
703
|
+
it "status should be 'received' for a new booking" do
|
704
|
+
Booking.new.status.should match_enum(:received)
|
705
|
+
end
|
706
|
+
end
|
707
|
+
```
|
550
708
|
|
551
709
|
Of course `Booking.new.status.should === :received` still works, but is liable to produce false positives.
|
552
710
|
|
@@ -577,13 +735,13 @@ And finally run tests:
|
|
577
735
|
* Initial Version Copyright (c) 2005 Trevor Squires
|
578
736
|
* Rails 3 Updates Copyright (c) 2010 Pivotal Labs
|
579
737
|
* Initial Test Suite Copyright (c) 2011 Sergey Potapov
|
580
|
-
* Subsequent Updates Copyright (c) 2011 Arthur Shagall
|
738
|
+
* Subsequent Updates Copyright (c) 2011-2012 Arthur Shagall
|
581
739
|
|
582
740
|
Released under the MIT License. See the LICENSE file for more details.
|
583
741
|
|
584
742
|
## Contributing
|
585
743
|
|
586
|
-
Contributions are welcome. However,
|
744
|
+
Contributions are welcome. However, please make sure of the following before issuing a pull request:
|
587
745
|
|
588
746
|
* All specs are passing.
|
589
747
|
* Any new features have test coverage.
|