enumerate_it 1.2.0 → 1.2.1

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGI4ZDc1NjJkOTdiODA5Zjg4Y2ExMmMzNGY2OWUzODkxZWVlNmY4Ng==
5
+ data.tar.gz: !binary |-
6
+ M2YxZjM3NjhkYzg5NTVhM2ViODQ1YjU4NzNkNjYxMzYzN2U2YjZkNA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZmM2MDI1OWRmNzlmNjgwMWI1YzZlMzdhNjg3NzFlOWFmODgxNTQzYzMzOGQz
10
+ NWQ0YWUzYTQyYzc1MDk2OGE4NDYyMWU5OTA0OTliYzUzNTY0MjFjNmFlMGZk
11
+ ZjMzODE0Y2VjZjYyM2NhMTM5M2ZiNjdlOTVmODM1MTAwNzUzYTM=
12
+ data.tar.gz: !binary |-
13
+ OWNkZmY1ZTc5YTU4OTdkZmM2YzViMTgxYTI5NWJjNzlkZDQ2ZDMwYmEzZDYx
14
+ ZTk4YzRmNjg3MTI3MjE0ZjgwNGZjMjVlZTgxNjA0OGQ0NmNjZjM2OWE4OThh
15
+ Mzk3ZmFhMTc3Zjk0M2EzYjBkMDVlMGUzYTU5ZDQwNGFlMzE0YzA=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- enumerate_it (1.2.0)
4
+ enumerate_it (1.2.1)
5
5
  activesupport (>= 3.0.0)
6
6
 
7
7
  GEM
data/README.markdown ADDED
@@ -0,0 +1,508 @@
1
+ # EnumerateIt - Ruby Enumerations
2
+
3
+ [![Build Status](https://travis-ci.org/cassiomarques/enumerate_it.png?branch=master)](https://travis-ci.org/cassiomarques/enumerate_it)
4
+ [![Gem Version](https://badge.fury.io/rb/enumerate_it.png)](http://badge.fury.io/rb/enumerate_it)
5
+
6
+ Author: Cássio Marques - cassiommc at gmail
7
+
8
+ ## Description
9
+
10
+ Ok, I know there are a lot of different solutions to this problem. But none of
11
+ them solved my problem, so here's EnumerateIt. I needed to build a Rails
12
+ application around a legacy database and this database was filled with those
13
+ small, unchangeable tables used to create foreign key constraints everywhere.
14
+
15
+ ### For example:
16
+
17
+ Table "public.relationshipstatus"
18
+
19
+ Column | Type | Modifiers
20
+ -------------+---------------+-----------
21
+ code | character(1) | not null
22
+ description | character(11) |
23
+
24
+ Indexes:
25
+ "relationshipstatus_pkey" PRIMARY KEY, btree (code)
26
+
27
+ SELECT * FROM relationshipstatus;
28
+
29
+ code | description
30
+ -------+--------------
31
+ 1 | Single
32
+ 2 | Married
33
+ 3 | Widow
34
+ 4 | Divorced
35
+
36
+ And then I had things like a people table with a 'relationship_status' column
37
+ with a foreign key pointing to the relationshipstatus table.
38
+
39
+ While this is a good thing from the database normalization perspective,
40
+ managing this values in my tests was very hard. Doing database joins just to
41
+ get the description of some value was absurd. And, more than this, referencing
42
+ them in my code using magic numbers was terrible and meaningless: What does it
43
+ mean when we say that someone or something is '2'?
44
+
45
+ Enter EnumerateIt.
46
+
47
+ ## About versions compatibility
48
+
49
+ Versions 1.x.x are NOT backwards compatible with 0.x.x versions. The biggest
50
+ difference is that on 1.0.0 you need to `extend` the EnumerateIt module inside
51
+ classes that are going to have enumerated attributes, while in past versions
52
+ you would use `include`.
53
+
54
+ ## Creating enumerations
55
+
56
+ Enumerations are created as models, but you can put then anywhere in your
57
+ application. In Rails applications, you can put them inside models/.
58
+
59
+ ``` ruby
60
+ class RelationshipStatus < EnumerateIt::Base
61
+ associate_values(
62
+ :single => [1, 'Single'],
63
+ :married => [2, 'Married'],
64
+ :widow => [3, 'Widow'],
65
+ :divorced => [4, 'Divorced']
66
+ )
67
+ end
68
+ ```
69
+
70
+ This will create some nice stuff:
71
+
72
+ * Each enumeration's value will turn into a constant:
73
+
74
+ ``` ruby
75
+ RelationshipStatus::SINGLE
76
+ #=> 1
77
+
78
+ RelationshipStatus::MARRIED
79
+ #=> 2
80
+ ```
81
+
82
+ * You can retrieve a list with all the enumeration codes:
83
+
84
+ ``` ruby
85
+ RelationshipStatus.list
86
+ #=> [1, 2, 3, 4]
87
+ ```
88
+
89
+ * You can get an array of options, ready to use with the 'select',
90
+ 'select_tag', etc family of Rails helpers.
91
+
92
+ ``` ruby
93
+ RelationshipStatus.to_a
94
+ #=> [["Divorced", 4], ["Married", 2], ["Single", 1], ["Widow", 3]]
95
+ ```
96
+
97
+ * You can retrieve a list with values for a group of enumeration constants.
98
+
99
+ ``` ruby
100
+ RelationshipStatus.values_for %w(MARRIED SINGLE)
101
+ #=> [2, 1]
102
+ ```
103
+
104
+ * You can retrieve the value for a specific enumeration constant:
105
+
106
+ ``` ruby
107
+ RelationshipStatus.value_for("MARRIED")
108
+ #=> 2
109
+ ```
110
+
111
+ * You can retrieve the symbol used to declare a specific enumeration value:
112
+
113
+ ``` ruby
114
+ RelationshipStatus.key_for(RelationshipStatus::MARRIED)
115
+ #=> :married
116
+ ```
117
+
118
+ * You can iterate over the list of the enumeration's values:
119
+
120
+ ``` ruby
121
+ RelationshipStatus.each_value { |value| ... }
122
+ ```
123
+
124
+ * You can iterate over the list of the enumeration's translations:
125
+
126
+ ``` ruby
127
+ RelationshipStatus.each_translation { |translation| ... }
128
+ ```
129
+
130
+ * You can ask for the enumeration's length:
131
+
132
+ ``` ruby
133
+ RelationshipStatus.length
134
+ #=> 4
135
+ ```
136
+
137
+ * You can manipulate the hash used to create the enumeration:
138
+
139
+ ``` ruby
140
+ RelationshipStatus.enumeration
141
+ #=> returns the exact hash used to define the enumeration
142
+ ```
143
+
144
+
145
+ You can also create enumerations in the following ways:
146
+
147
+ * Passing an array of symbols, so that the respective value for each symbol
148
+ will be the stringified version of the symbol itself:
149
+
150
+ ``` ruby
151
+ class RelationshipStatus < EnumerateIt::Base
152
+ associate_values :married, :single
153
+ end
154
+
155
+ RelationshipStatus::MARRIED
156
+ #=> "married"
157
+ ```
158
+
159
+ * Passing hashes where the value for each key/pair does not include a
160
+ translation. In this case, the I18n feature will be used (more on this
161
+ below):
162
+
163
+ ``` ruby
164
+ class RelationshipStatus < EnumerateIt::Base
165
+ associate_values :married => 1, :single => 2
166
+ end
167
+ ```
168
+
169
+
170
+ ### Defining a default sort mode
171
+
172
+ When calling methods like `to_a` and `to_json`, the returned values will be
173
+ sorted using the translation for each one of the enumeration values. If you
174
+ want to overwrite the default sort mode, you can use the `sort_by` class
175
+ method.
176
+
177
+ ``` ruby
178
+ class RelationshipStatus < EnumerateIt::Base
179
+ associate_values :married => 1, :single => 2
180
+
181
+ sort_by :value
182
+ end
183
+ ```
184
+
185
+ The `sort_by` methods accept one of the following values:
186
+
187
+ * `:translation`: The default behavior, will sort the returned values based
188
+ on translations.
189
+ * `:value`: Will sort the returned values based on values.
190
+ * `:name`: Will sort the returned values based on the name of each
191
+ enumeration option.
192
+ * `:none`: Will return values in order that was passed to associate_values
193
+ call.
194
+
195
+
196
+ ## Using enumerations
197
+
198
+ The cool part is that you can use these enumerations with any class, be it an
199
+ ActiveRecord instance or not.
200
+
201
+ ``` ruby
202
+ class Person
203
+ extend EnumerateIt
204
+ attr_accessor :relationship_status
205
+
206
+ has_enumeration_for :relationship_status, :with => RelationshipStatus
207
+ end
208
+ ```
209
+
210
+ The :with option is not required. If you ommit it, EnumerateIt will try to
211
+ load an enumeration class based on the camelized attribute name.
212
+
213
+ This will create:
214
+
215
+ * A humanized description for the values of the enumerated attribute:
216
+
217
+ ``` ruby
218
+ p = Person.new
219
+ p.relationship_status = RelationshipStatus::DIVORCED
220
+ p.relationship_status_humanize
221
+ #=> 'Divorced'
222
+ ```
223
+
224
+ * If you don't supply a humanized string to represent an option, EnumerateIt
225
+ will use a 'humanized' version of the hash's key to humanize the
226
+ attribute's value:
227
+
228
+ ``` ruby
229
+ class RelationshipStatus < EnumerateIt::Base
230
+ associate_values(
231
+ :married => 1,
232
+ :single => 2
233
+ )
234
+ end
235
+
236
+ p = Person.new
237
+ p.relationship_status = RelationshipStatus::MARRIED
238
+ p.relationship_status_humanize
239
+ #=> 'Married'
240
+ ```
241
+
242
+ * The associated enumerations can be retrieved with the 'enumerations' class
243
+ method.
244
+
245
+ ``` ruby
246
+ Person.enumerations[:relationship_status]
247
+ #=> RelationshipStatus
248
+ ```
249
+
250
+ * If you pass the :create_helpers option as 'true', it will create a helper
251
+ method for each enumeration option (this option defaults to false):
252
+
253
+ ``` ruby
254
+ class Person < ActiveRecord::Base
255
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => true
256
+ end
257
+
258
+ p = Person.new
259
+ p.relationship_status = RelationshipStatus::MARRIED
260
+
261
+ p.married?
262
+ #=> true
263
+
264
+ p.divorced?
265
+ #=> false
266
+ ```
267
+
268
+ * It's also possible to "namespace" the created helper methods, passing a
269
+ hash to the :create_helpers option. This can be useful when two or more of
270
+ the enumerations used share the same constants.
271
+
272
+ ``` ruby
273
+ class Person < ActiveRecord::Base
274
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :prefix => true }
275
+ end
276
+
277
+ p = Person.new
278
+ p.relationship_status = RelationshipStatus::MARRIED
279
+
280
+ p.relationship_status_married?
281
+ #=> true
282
+
283
+ p.relationship_status_divoced?
284
+ #=> false
285
+ ```
286
+
287
+ * You can define polymorphic behavior for the enum values, so you can define
288
+ a class for each of them:
289
+
290
+ ``` ruby
291
+ class RelationshipStatus < EnumerateIt::Base
292
+ associate_values :married, :single
293
+
294
+ class Married
295
+ def saturday_night
296
+ "At home with the kids"
297
+ end
298
+ end
299
+
300
+ class Single
301
+ def saturday_night
302
+ "Party Hard!"
303
+ end
304
+ end
305
+ end
306
+
307
+ class Person < ActiveRecord::Base
308
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => true }
309
+ end
310
+
311
+ p = Person.new
312
+ p.relationship_status = RelationshipStatus::MARRIED
313
+ p.relationship_status_object.saturday_night
314
+ #=> "At home with the kids"
315
+
316
+ p.relationship_status = RelationshipStatus::SINGLE
317
+ p.relationship_status_object.saturday_night
318
+ #=> "Party Hard!"
319
+ ```
320
+
321
+ You can also change the suffix '_object', using the :suffix option:
322
+
323
+ ``` ruby
324
+ class Person < ActiveRecord::Base
325
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => { :suffix => "_mode" } }
326
+ end
327
+
328
+ p.relationship_status_mode.saturday_night
329
+ ```
330
+
331
+ * The :create_helpers also creates some mutator helper methods, that can be
332
+ used to change the attribute's value.
333
+
334
+ ``` ruby
335
+ class Person < ActiveRecord::Base
336
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => true
337
+ end
338
+
339
+ p = Person.new
340
+ p.married!
341
+
342
+ p.married?
343
+ #=> true
344
+
345
+ p.divorced?
346
+ #=> false
347
+ ```
348
+
349
+ * If you pass the :create_scopes option as 'true', it will create a scope
350
+ method for each enumeration option (this option defaults to false):
351
+
352
+ ``` ruby
353
+ class Person < ActiveRecord::Base
354
+ has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_scopes => true
355
+ end
356
+
357
+ Person.married.to_sql
358
+ #=> SELECT "people".* FROM "people" WHERE "people"."relationship_status" = 1
359
+ ```
360
+
361
+
362
+ NOTE: The :create_scopes option can only be used for Rails.version >= 3.0.0.
363
+
364
+ * If your class can manage validations and responds to
365
+ :validates_inclusion_of, it will create this validation:
366
+
367
+ ``` ruby
368
+ class Person < ActiveRecord::Base
369
+ has_enumeration_for :relationship_status, :with => RelationshipStatus
370
+ end
371
+
372
+ p = Person.new(:relationship_status => 6) # there is no '6' value in the enumeration
373
+ p.valid?
374
+ #=> false
375
+ p.errors[:relationship_status]
376
+ #=> "is not included in the list"
377
+ ```
378
+
379
+ * If your class can manage validations and responds to
380
+ :validates_presence_of, you can pass the :required options as true and
381
+ this validation will be created for you (this option defaults to false):
382
+
383
+ ``` ruby
384
+ class Person < ActiveRecord::Base
385
+ has_enumeration_for :relationship_status, :required => true
386
+ end
387
+
388
+ p = Person.new :relationship_status => nil
389
+ p.valid?
390
+ #=> false
391
+ p.errors[:relationship_status]
392
+ #=> "can't be blank"
393
+ ```
394
+
395
+
396
+ Remember that in Rails 3 you can add validations to any kind of class and not
397
+ only to those derived from ActiveRecord::Base.
398
+
399
+ ## I18n
400
+
401
+ I18n lookup is provided on both '_humanized' and 'Enumeration#to_a' methods,
402
+ given the hash key is a Symbol. The I18n strings are located on
403
+ enumerations.'enumeration_name'.'key' :
404
+
405
+ ``` yaml
406
+ # your locale file
407
+ pt:
408
+ enumerations:
409
+ relationship_status:
410
+ married: Casado
411
+ ```
412
+
413
+ ``` ruby
414
+ class RelationshipStatus < EnumerateIt::Base
415
+ associate_values(
416
+ :married => 1,
417
+ :single => 2,
418
+ :divorced => [3, "He's divorced"]
419
+ )
420
+ end
421
+
422
+ p = Person.new
423
+ p.relationship_status = RelationshipStatus::MARRIED
424
+ p.relationship_status_humanize
425
+ #=> 'Casado'
426
+
427
+ p.relationship_status = RelationshipStatus::SINGLE
428
+ p.relationship_status_humanize # nonexistent key
429
+ #=> 'Single'
430
+
431
+ p.relationship_status = RelationshipStatus::DIVORCED
432
+ p.relationship_status_humanize # uses the provided string
433
+ #=> 'He's divorced'
434
+ ```
435
+
436
+ You can also translate specific values:
437
+
438
+ ``` ruby
439
+ RelationshipStatus.t(1)
440
+ #=> 'Casado'
441
+ ```
442
+
443
+ ## Installation
444
+
445
+ ``` bash
446
+ gem install enumerate_it
447
+ ```
448
+
449
+ ## Using with Rails
450
+
451
+ * Add the gem to your Gemfile:
452
+
453
+ ``` ruby
454
+ gem "enumerate_it"
455
+ ```
456
+
457
+ * Run the install generator:
458
+
459
+ ``` bash
460
+ rails generate enumerate_it:install
461
+ ```
462
+
463
+
464
+ An interesting approach to use it in Rails apps is to create an
465
+ app/enumerations folder and add it to your autoload path in
466
+ config/application.rb:
467
+
468
+ ``` ruby
469
+ module YourApp
470
+ class Application < Rails::Application
471
+ config.autoload_paths << "#{Rails.root}/app/enumerations"
472
+ end
473
+ end
474
+ ```
475
+
476
+ There is also a Rails Generator that you can use to generate enumerations and
477
+ their locale files. Take a look at how to use it running
478
+
479
+ ``` bash
480
+ rails generate enumerate_it:enum --help
481
+ ```
482
+
483
+ ## Why did you reinvent the wheel?
484
+
485
+ There are other similar solutions to the problem out there, but I could not
486
+ find one that worked both with strings and integers as the enumerations'
487
+ codes. I had both situations in my legacy database.
488
+
489
+ ## Why defining enumerations outside the class that use it?
490
+
491
+ * I think it's cleaner.
492
+ * You can add behaviour to the enumeration class.
493
+ * You can reuse the enumeration inside other classes.
494
+
495
+ ## Note on Patches/Pull Requests
496
+
497
+ * Fork the project.
498
+ * Make your feature addition or bug fix.
499
+ * Add tests for it. This is important so I don't break it in a future
500
+ version unintentionally.
501
+ * Commit, do not mess with rakefile, version, or history. (if you want to
502
+ have your own version, that is fine but bump version in a commit by itself
503
+ I can ignore when I pull)
504
+ * Send me a pull request. Bonus points for topic branches.
505
+
506
+ ## Copyright
507
+
508
+ Copyright (c) 2010 Cássio Marques. See LICENSE for details.
@@ -1,3 +1,3 @@
1
1
  module EnumerateIt
2
- VERSION = "1.2.0"
2
+ VERSION = "1.2.1"
3
3
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumerate_it
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 1.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Cássio Marques
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-16 00:00:00.000000000 Z
11
+ date: 2014-03-07 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: activerecord
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: pry
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: pry-nav
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,15 +90,11 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ! '>='
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
- description: Have a legacy database and need some enumerations in your models to match
111
- those stupid '4 rows/2 columns' tables with foreign keys and stop doing joins just
112
- to fetch a simple description? Or maybe use some integers instead of strings as
113
- the code for each value of your enumerations? Here's EnumerateIt.
97
+ description: Enumerations for Ruby with some magic powers!
114
98
  email:
115
99
  - cassiommc@gmail.com
116
100
  executables: []
@@ -123,7 +107,7 @@ files:
123
107
  - Gemfile
124
108
  - Gemfile.lock
125
109
  - LICENSE
126
- - README.rdoc
110
+ - README.markdown
127
111
  - Rakefile
128
112
  - enumerate_it.gemspec
129
113
  - lib/enumerate_it.rb
@@ -146,33 +130,26 @@ files:
146
130
  - spec/support/test_classes.rb
147
131
  homepage: http://github.com/cassiomarques/enumerate_it
148
132
  licenses: []
133
+ metadata: {}
149
134
  post_install_message:
150
135
  rdoc_options: []
151
136
  require_paths:
152
137
  - lib
153
138
  required_ruby_version: !ruby/object:Gem::Requirement
154
- none: false
155
139
  requirements:
156
140
  - - ! '>='
157
141
  - !ruby/object:Gem::Version
158
142
  version: '0'
159
- segments:
160
- - 0
161
- hash: 1153526174871300187
162
143
  required_rubygems_version: !ruby/object:Gem::Requirement
163
- none: false
164
144
  requirements:
165
145
  - - ! '>='
166
146
  - !ruby/object:Gem::Version
167
147
  version: '0'
168
- segments:
169
- - 0
170
- hash: 1153526174871300187
171
148
  requirements: []
172
149
  rubyforge_project:
173
- rubygems_version: 1.8.24
150
+ rubygems_version: 2.1.4
174
151
  signing_key:
175
- specification_version: 3
152
+ specification_version: 4
176
153
  summary: Ruby Enumerations
177
154
  test_files:
178
155
  - spec/enumerate_it/base_spec.rb
data/README.rdoc DELETED
@@ -1,366 +0,0 @@
1
- = EnumerateIt - Ruby Enumerations
2
-
3
- {<img src="https://secure.travis-ci.org/cassiomarques/enumerate_it.png?branch=master" alt="Build Status" />}[http://travis-ci.org/cassiomarques/enumerate_it]
4
-
5
- Author: Cássio Marques - cassiommc at gmail
6
-
7
- == Description
8
-
9
- Ok, I know there are a lot of different solutions to this problem. But none of them solved my problem,
10
- so here's EnumerateIt. I needed to build a Rails application around a legacy database and this database was
11
- filled with those small, unchangeable tables used to create foreign key constraints everywhere.
12
-
13
- === For example:
14
-
15
- Table "public.relationshipstatus"
16
- Column | Type | Modifiers
17
- -------------+---------------+-----------
18
- code | character(1) | not null
19
- description | character(11) |
20
- Indexes:
21
- "relationshipstatus_pkey" PRIMARY KEY, btree (code)
22
-
23
- select * from relationshipstatus;
24
- code | description
25
- -------+--------------
26
- 1 | Single
27
- 2 | Married
28
- 3 | Widow
29
- 4 | Divorced
30
-
31
-
32
- And then I had things like a people table with a 'relationship_status' column with a foreign key
33
- pointing to the relationshipstatus table.
34
-
35
- While this is a good thing from the database normalization perspective, managing this values in
36
- my tests was very hard. Doing database joins just to get the description of some value was absurd.
37
- And, more than this, referencing them in my code using magic numbers was terrible and meaningless:
38
- What does it mean when we say that someone or something is '2'?
39
-
40
- Enter EnumerateIt.
41
-
42
- == About versions compatibility
43
-
44
- Versions 1.x.x are NOT backwards compatible with 0.x.x versions. The biggest difference is that on 1.0.0 you need to `extend` the EnumerateIt
45
- module inside classes that are going to have enumerated attributes, while in past versions you would use `include`.
46
-
47
- == Creating enumerations
48
-
49
- Enumerations are created as models, but you can put then anywhere in your application. In Rails
50
- applications, you can put them inside models/.
51
-
52
- class RelationshipStatus < EnumerateIt::Base
53
- associate_values(
54
- :single => [1, 'Single'],
55
- :married => [2, 'Married'],
56
- :widow => [3, 'Widow'],
57
- :divorced => [4, 'Divorced']
58
- )
59
- end
60
-
61
- This will create some nice stuff:
62
-
63
- * Each enumeration's value will turn into a constant:
64
-
65
- RelationshipStatus::SINGLE # returns 1
66
- RelationshipStatus::MARRIED # returns 2 and so on...
67
-
68
- * You can retrieve a list with all the enumeration codes:
69
-
70
- RelationshipStatus.list # [1,2,3,4]
71
-
72
- * You can get an array of options, ready to use with the 'select', 'select_tag', etc family of Rails helpers.
73
-
74
- RelationshipStatus.to_a # [["Divorced", 4],["Married", 2],["Single", 1],["Widow", 3]]
75
-
76
- * You can retrieve a list with values for a group of enumeration constants.
77
-
78
- RelationshipStatus.values_for %w(MARRIED SINGLE) # [2, 1]
79
-
80
- * You can retrieve the value for a specific enumeration constant:
81
-
82
- RelationshipStatus.value_for("MARRIED") # 2
83
-
84
- * You can retrieve the symbol used to declare a specific enumeration value:
85
-
86
- RelationshipStatus.key_for(RelationshipStatus::MARRIED) # :married
87
-
88
- * You can iterate over the list of the enumeration's values:
89
-
90
- RelationshipStatus.each_value { |value| # ... }
91
-
92
- * You can iterate over the list of the enumeration's translations:
93
-
94
- RelationshipStatus.each_translation { |translation| # ... }
95
-
96
- * You can ask for the enumeration's length:
97
-
98
- RelationshipStatus.length # 4
99
-
100
- * You can manipulate the hash used to create the enumeration:
101
-
102
- RelationshipStatus.enumeration # returns the exact hash used to define the enumeration
103
-
104
- You can also create enumerations in the following ways:
105
-
106
- * Passing an array of symbols, so that the respective value for each symbol will be the stringified version of the symbol itself:
107
-
108
- class RelationshipStatus < EnumerateIt::Base
109
- associate_values :married, :single
110
- end
111
-
112
- RelationshipStatus::MARRIED # returns "married" and so on
113
-
114
- * Passing hashes where the value for each key/pair does not include a translation. In this case, the I18n feature will be used (more on this below):
115
-
116
- class RelationshipStatus < EnumerateIt::Base
117
- associate_values :married => 1, :single => 2
118
- end
119
-
120
- === Defining a default sort mode
121
-
122
- When calling methods like `to_a` and `to_json`, the returned values will be sorted using the translation for each one of the enumeration values. If you want
123
- to overwrite the default sort mode, you can use the `sort_mode` class method.
124
-
125
- class RelationshipStatus < EnumerateIt::Base
126
- associate_values :married => 1, :single => 2
127
-
128
- sort_by :value
129
- end
130
-
131
- The `sort_by` methods accept one of the following values:
132
-
133
- * `:translation`: The default behavior, will sort the returned values based on translations.
134
- * `:value`: Will sort the returned values based on values.
135
- * `:name`: Will sort the returned values based on the name of each enumeration option.
136
- * `:none`: Will return values in order that was passed to associate_values call.
137
-
138
- == Using enumerations
139
-
140
- The cool part is that you can use these enumerations with any class, be it an ActiveRecord instance
141
- or not.
142
-
143
- class Person
144
- extend EnumerateIt
145
- attr_accessor :relationship_status
146
-
147
- has_enumeration_for :relationship_status, :with => RelationshipStatus
148
- end
149
-
150
- The :with option is not required. If you ommit it, EnumerateIt will try to load an enumeration class based on the camelized attribute name.
151
-
152
- This will create:
153
-
154
- * A humanized description for the values of the enumerated attribute:
155
-
156
- p = Person.new
157
- p.relationship_status = RelationshipStatus::DIVORCED
158
- p.relationship_status_humanize # => 'Divorced'
159
-
160
- * If you don't supply a humanized string to represent an option, EnumerateIt will use a 'humanized' version of the hash's key to humanize the attribute's value:
161
-
162
- class RelationshipStatus < EnumerateIt::Base
163
- associate_values(
164
- :married => 1,
165
- :single => 2
166
- )
167
- end
168
-
169
- p = Person.new
170
- p.relationship_status = RelationshipStatus::MARRIED
171
- p.relationship_status_humanize # => 'Married'
172
-
173
- * The associated enumerations can be retrieved with the 'enumerations' class method.
174
-
175
- Person.enumerations[:relationship_status] # => RelationshipStatus
176
-
177
- * If you pass the :create_helpers option as 'true', it will create a helper method for each enumeration option (this option defaults to false):
178
-
179
- class Person < ActiveRecord::Base
180
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => true
181
- end
182
-
183
- p = Person.new
184
- p.relationship_status = RelationshipStatus::MARRIED
185
- p.married? #=> true
186
- p.divorced? #=> false
187
-
188
- * It's also possible to "namespace" the created helper methods, passing a hash to the :create_helpers option.
189
- This can be useful when two or more of the enumerations used share the same constants.
190
-
191
- class Person < ActiveRecord::Base
192
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :prefix => true }
193
- end
194
-
195
- p = Person.new
196
- p.relationship_status = RelationshipStatus::MARRIED
197
- p.relationship_status_married? #=> true
198
- p.relationship_status_divoced? #=> false
199
-
200
- * You can define polymorphic behavior for the enum values, so you can define a class for each of
201
- them:
202
-
203
- class RelationshipStatus < EnumerateIt::Base
204
- associate_values :married, :single
205
-
206
- class Married
207
- def saturday_night
208
- "At home with the kids"
209
- end
210
- end
211
-
212
- class Single
213
- def saturday_night
214
- "Party Hard!"
215
- end
216
- end
217
- end
218
-
219
- class Person < ActiveRecord::Base
220
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => true }
221
- end
222
-
223
- p = Person.new
224
- p.relationship_status = RelationshipStatus::MARRIED
225
- p.relationship_status_object.saturday_night # => "At home with the kids"
226
-
227
- p.relationship_status = RelationshipStatus::SINGLE
228
- p.relationship_status_object.saturday_night # => "Party Hard!"
229
-
230
- You can also change the suffix '_object', using the :suffix option:
231
-
232
- class Person < ActiveRecord::Base
233
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => { :suffix => "_mode" } }
234
- end
235
-
236
- p.relationship_status_mode.saturday_night
237
-
238
- * The :create_helpers also creates some mutator helper methods, that can be used to change the attribute's value.
239
-
240
- class Person < ActiveRecord::Base
241
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => true
242
- end
243
-
244
- p = Person.new
245
- p.married!
246
- p.married? #=> true
247
- p.divorced? #=> false
248
-
249
- * If you pass the :create_scopes option as 'true', it will create a scope method for each enumeration option (this option defaults to false):
250
-
251
- class Person < ActiveRecord::Base
252
- has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_scopes => true
253
- end
254
-
255
- Person.married.to_sql # => SELECT "people".* FROM "people" WHERE "people"."relationship_status" = 1
256
-
257
- NOTE: The :create_scopes option can only be used for Rails.version >= 3.0.0.
258
-
259
- * If your class can manage validations and responds to :validates_inclusion_of, it will create this validation:
260
-
261
- class Person < ActiveRecord::Base
262
- has_enumeration_for :relationship_status, :with => RelationshipStatus
263
- end
264
-
265
- p = Person.new :relationship_status => 6 # => there is no '6' value in the enumeration
266
- p.valid? # => false
267
- p.errors[:relationship_status] # => "is not included in the list"
268
-
269
- * If your class can manage validations and responds to :validates_presence_of, you can pass the :required options as true and this validation will be created for you (this option defaults to false):
270
-
271
- class Person < ActiveRecord::Base
272
- has_enumeration_for :relationship_status, :required => true
273
- end
274
-
275
- p = Person.new :relationship_status => nil
276
- p.valid? # => false
277
- p.errors[:relationship_status] # => "can't be blank"
278
-
279
-
280
- Remember that in Rails 3 you can add validations to any kind of class and not only to those derived from
281
- ActiveRecord::Base.
282
-
283
- == I18n
284
-
285
- I18n lookup is provided on both '_humanized' and 'Enumeration#to_a' methods, given the hash key is a Symbol. The I18n strings are
286
- located on enumerations.'enumeration_name'.'key' :
287
-
288
- class RelationshipStatus < EnumerateIt::Base
289
- associate_values(
290
- :married => 1,
291
- :single => 2,
292
- :divorced => [3, 'He's divorced']
293
- )
294
- end
295
-
296
- # your locale file
297
- pt:
298
- enumerations:
299
- relationship_status:
300
- married: Casado
301
-
302
- p = Person.new
303
- p.relationship_status = RelationshipStatus::MARRIED
304
- p.relationship_status_humanize # => 'Casado'
305
-
306
- p.relationship_status = RelationshipStatus::SINGLE
307
- p.relationship_status_humanize # => 'Single' => nonexistent key
308
-
309
- p.relationship_status = RelationshipStatus::DIVORCED
310
- p.relationship_status_humanize # => 'He's divorced' => uses the provided string
311
-
312
- You can also translate specific values:
313
-
314
- RelationshipStatus.t(1) # => 'Casado'
315
-
316
- == Installation
317
-
318
- gem install enumerate_it
319
-
320
- == Using with Rails
321
-
322
- * Add the gem to your Gemfile:
323
-
324
- gem "enumerate_it"
325
-
326
- * Run the install generator:
327
-
328
- rails g enumerate_it:install
329
-
330
- An interesting approach to use it in Rails apps is to create an app/enumerations folder and add it to your autoload path in config/application.rb:
331
-
332
- module YourApp
333
- class Application < Rails::Application
334
- config.autoload_paths << "#{Rails.root}/app/enumerations"
335
- end
336
- end
337
-
338
- There is also a Rails Generator that you can use to generate enumerations and their locale files. Take a look at how to use it running
339
-
340
- rails generate enumerate_it:enum --help
341
-
342
- == Why did you reinvent the wheel?
343
-
344
- There are other similar solutions to the problem out there, but I could not find one that
345
- worked both with strings and integers as the enumerations' codes. I had both situations in
346
- my legacy database.
347
-
348
- == Why defining enumerations outside the class that use it?
349
-
350
- * I think it's cleaner.
351
- * You can add behaviour to the enumeration class.
352
- * You can reuse the enumeration inside other classes.
353
-
354
- == Note on Patches/Pull Requests
355
-
356
- * Fork the project.
357
- * Make your feature addition or bug fix.
358
- * Add tests for it. This is important so I don't break it in a
359
- future version unintentionally.
360
- * Commit, do not mess with rakefile, version, or history.
361
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
362
- * Send me a pull request. Bonus points for topic branches.
363
-
364
- == Copyright
365
-
366
- Copyright (c) 2010 Cássio Marques. See LICENSE for details.