enumerate_it 1.3.1 → 1.4.0.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f38356eaa7e97dd863aebe8a0a5b05043176bbd7
4
- data.tar.gz: e409af191da4875f1649eea4dabc0f1f25e360cd
3
+ metadata.gz: 75cf6c3f112a2575798bcf189871687e81a46e19
4
+ data.tar.gz: 31c1f6b460883f3b152c73730e0fed10c9c037e3
5
5
  SHA512:
6
- metadata.gz: 17644e925e069bf0488a0bb2d146eb104eca4aa7fa7a57e2c6d7f5131dee68ab4b80095cad6e45ce58a8ea7f77b02c4613c3ecb2e3ec8c5b3ce7e20a81be89fe
7
- data.tar.gz: 5abb6fb31ad4360d37e3545029c2b2e889c5d97fa0f2a35625b29e9595be0b0b91cfa2e27dcd69709ab91b9577a4661348dd97ea589cab3e337b0508b3924adb
6
+ metadata.gz: b6c4da4b694618f9eedc01f3234469df4d8192beaa431adac5f7e0f0168858e3a6f311f470b10e0b45cc6dcbdbb9662f164cb4193277e9856c9115d2c1dacb75
7
+ data.tar.gz: 5bfe4f685fc279a834b23946aa25f1aff2435f0dfe3357bf3b4af213c87a02e31de98e81dcd1a362ca21c5cf0f22a88309338a98a00848166844657a81265e66
data/.rubocop.yml CHANGED
@@ -38,3 +38,15 @@ Style/MultilineMethodCallIndentation:
38
38
  Style/PredicateName:
39
39
  Exclude:
40
40
  - 'lib/enumerate_it/class_methods.rb'
41
+
42
+ Style/GuardClause:
43
+ MinBodyLength: 3
44
+
45
+ RSpec/MultipleExpectations:
46
+ Enabled: false
47
+
48
+ RSpec/NestedGroups:
49
+ Enabled: false
50
+
51
+ RSpec/MessageExpectation:
52
+ Enabled: false
data/.travis.yml CHANGED
@@ -33,3 +33,7 @@ matrix:
33
33
  gemfile: gemfiles/rails_5.0.gemfile
34
34
  - rvm: 2.1.10
35
35
  gemfile: gemfiles/rails_5.0.gemfile
36
+
37
+ addons:
38
+ code_climate:
39
+ repo_token: 60e4a18e2a4bc86a98f92847f16756876c13d1e772058a9b3296643b04a697d7
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in enumerate_it.gemspec
4
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- enumerate_it (1.3.1)
4
+ enumerate_it (1.4.0.rc1)
5
5
  activesupport (>= 3.0.0)
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
10
  activesupport (5.0.0.1)
11
11
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -22,8 +22,8 @@ GEM
22
22
  diff-lcs (1.2.5)
23
23
  i18n (0.7.0)
24
24
  method_source (0.8.2)
25
- minitest (5.9.0)
26
- parser (2.3.1.2)
25
+ minitest (5.9.1)
26
+ parser (2.3.1.4)
27
27
  ast (~> 2.2)
28
28
  powerpack (0.1.1)
29
29
  pry (0.10.4)
@@ -31,12 +31,12 @@ GEM
31
31
  method_source (~> 0.8.1)
32
32
  slop (~> 3.4)
33
33
  rainbow (2.1.0)
34
- rake (11.2.2)
34
+ rake (11.3.0)
35
35
  rspec (3.5.0)
36
36
  rspec-core (~> 3.5.0)
37
37
  rspec-expectations (~> 3.5.0)
38
38
  rspec-mocks (~> 3.5.0)
39
- rspec-core (3.5.2)
39
+ rspec-core (3.5.4)
40
40
  rspec-support (~> 3.5.0)
41
41
  rspec-expectations (3.5.0)
42
42
  diff-lcs (>= 1.2.0, < 2.0)
@@ -45,13 +45,13 @@ GEM
45
45
  diff-lcs (>= 1.2.0, < 2.0)
46
46
  rspec-support (~> 3.5.0)
47
47
  rspec-support (3.5.0)
48
- rubocop (0.42.0)
48
+ rubocop (0.44.1)
49
49
  parser (>= 2.3.1.1, < 3.0)
50
50
  powerpack (~> 0.1)
51
51
  rainbow (>= 1.99.1, < 3.0)
52
52
  ruby-progressbar (~> 1.7)
53
53
  unicode-display_width (~> 1.0, >= 1.0.1)
54
- rubocop-rspec (1.6.0)
54
+ rubocop-rspec (1.7.0)
55
55
  rubocop (>= 0.42.0)
56
56
  ruby-progressbar (1.8.1)
57
57
  slop (3.6.0)
@@ -59,7 +59,7 @@ GEM
59
59
  thread_safe (0.3.5)
60
60
  tzinfo (1.2.2)
61
61
  thread_safe (~> 0.1)
62
- unicode-display_width (1.1.0)
62
+ unicode-display_width (1.1.1)
63
63
 
64
64
  PLATFORMS
65
65
  ruby
@@ -75,4 +75,4 @@ DEPENDENCIES
75
75
  rubocop-rspec
76
76
 
77
77
  BUNDLED WITH
78
- 1.12.5
78
+ 1.13.2
data/README.md CHANGED
@@ -1,429 +1,401 @@
1
- # EnumerateIt - Ruby Enumerations
1
+ ![EnumerateIt Logo](https://raw.github.com/lucascaton/enumerate_it/master/enumerate_it.png)
2
+
3
+ Ruby Enumerations
2
4
 
3
5
  [![Build Status](https://travis-ci.org/lucascaton/enumerate_it.svg?branch=master)](https://travis-ci.org/lucascaton/enumerate_it)
4
6
  [![Gem Version](https://badge.fury.io/rb/enumerate_it.svg)](https://rubygems.org/gems/enumerate_it)
7
+ [![Code Climate](https://codeclimate.com/github/lucascaton/enumerate_it/badges/gpa.svg)](https://codeclimate.com/github/lucascaton/enumerate_it)
8
+ [![Changelog](https://img.shields.io/badge/changelog--brightgreen.svg?style=flat)](https://github.com/lucascaton/enumerate_it/releases)
5
9
 
6
- * **Author:** Cássio Marques
7
- * **Maintainer:** Lucas Caton
10
+ **EnumerateIt** helps you to declare and use enumerations in a very simple and flexible way.
8
11
 
9
- ## Description
12
+ ### Why would I want a gem if Rails already has native enumerations support?
10
13
 
11
- Ok, I know there are a lot of different solutions to this problem. But none of
12
- them solved my problem, so here's EnumerateIt. I needed to build a Rails
13
- application around a legacy database and this database was filled with those
14
- small, unchangeable tables used to create foreign key constraints everywhere.
14
+ Firstly, **EnumerateIt** works amazingly well along with **Rails** but it is not required!
15
+ It means you can add it to any **Ruby** project! 😀
15
16
 
16
- ### For example:
17
+ Secondly, Rails' enumerations has a problem:
18
+ [`ActiveRecord::Enum`](http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html) uses
19
+ `integers` instead of `strings`, which means that if you change your enumeration list oder in your
20
+ model, your database will no longer be consistent.
21
+ Database storage pricing is not a problem nowadays, so it's recommended to use `strings` columns.
17
22
 
18
- Table "public.relationshipstatus"
23
+ - [Installation](#installation)
24
+ - [Using with Rails](#using-with-rails)
25
+ - [Creating enumerations](#creating-enumerations)
26
+ - [Sorting enumerations](#sorting-enumerations)
27
+ - [Using enumerations](#using-enumerations)
28
+ - [I18n](#i18n)
29
+ - [Using enumerations to handle a legacy database](#using-enumerations-to-handle-a-legacy-database)
30
+ - [FAQ](#faq)
31
+ - [Changelog](#changelog)
19
32
 
20
- Column | Type | Modifiers
21
- -------------+---------------+-----------
22
- code | character(1) | not null
23
- description | character(11) |
33
+ ## Installation
24
34
 
25
- Indexes:
26
- "relationshipstatus_pkey" PRIMARY KEY, btree (code)
35
+ ```bash
36
+ gem install enumerate_it
37
+ ```
27
38
 
28
- SELECT * FROM relationshipstatus;
39
+ ## Using with Rails
29
40
 
30
- code | description
31
- -------+--------------
32
- 1 | Single
33
- 2 | Married
34
- 3 | Widow
35
- 4 | Divorced
41
+ Add the gem to your Gemfile:
36
42
 
37
- And then I had things like a people table with a 'relationship_status' column
38
- with a foreign key pointing to the relationshipstatus table.
43
+ ```ruby
44
+ gem 'enumerate_it'
45
+ ```
39
46
 
40
- While this is a good thing from the database normalization perspective,
41
- managing this values in my tests was very hard. Doing database joins just to
42
- get the description of some value was absurd. And, more than this, referencing
43
- them in my code using magic numbers was terrible and meaningless: What does it
44
- mean when we say that someone or something is '2'?
47
+ Run the install generator:
45
48
 
46
- Enter EnumerateIt.
49
+ ```bash
50
+ rails generate enumerate_it:install
51
+ ```
47
52
 
48
- ## Changelog
53
+ There is also a Rails Generator which generates enumerations and their locale files:
49
54
 
50
- Changes are maintained under [Releases](https://github.com/lucascaton/enumerate_it/releases).
55
+ ```bash
56
+ rails generate enumerate_it:enum --help
57
+ ```
51
58
 
52
59
  ## Creating enumerations
53
60
 
54
61
  Enumerations are created as classes and you should put them inside `app/enumerations` folder.
55
62
 
63
+ You can pass an array of symbols, so that the respective value for each symbol will be the
64
+ stringified version of the symbol itself:
65
+
56
66
  ```ruby
57
67
  class RelationshipStatus < EnumerateIt::Base
58
68
  associate_values(
59
- single: [1, 'Single'],
60
- married: [2, 'Married'],
61
- widow: [3, 'Widow'],
62
- divorced: [4, 'Divorced']
69
+ :single,
70
+ :married,
71
+ :divorced
63
72
  )
64
73
  end
65
74
  ```
66
75
 
67
76
  This will create some nice stuff:
68
77
 
69
- * Each enumeration's value will turn into a constant:
78
+ * Each enumeration's value will turn into a constant:
70
79
 
71
- ```ruby
72
- RelationshipStatus::SINGLE
73
- #=> 1
80
+ ```ruby
81
+ RelationshipStatus::SINGLE
82
+ # => 'single'
74
83
 
75
- RelationshipStatus::MARRIED
76
- #=> 2
77
- ```
84
+ RelationshipStatus::MARRIED
85
+ #=> 'married'
86
+ ```
78
87
 
79
- * You can retrieve a list with all the enumeration codes:
88
+ * You can retrieve a list with all the enumeration codes:
80
89
 
81
- ```ruby
82
- RelationshipStatus.list
83
- #=> [1, 2, 3, 4]
84
- ```
90
+ ```ruby
91
+ RelationshipStatus.list
92
+ #=> ['divorced', 'married', 'single']
93
+ ```
85
94
 
86
- * You can get an array of options, ready to use with the 'select',
87
- 'select_tag', etc family of Rails helpers.
95
+ * You can retrieve a JSON with all the enumeration codes:
88
96
 
89
- ```ruby
90
- RelationshipStatus.to_a
91
- #=> [["Divorced", 4], ["Married", 2], ["Single", 1], ["Widow", 3]]
92
- ```
97
+ ```ruby
98
+ RelationshipStatus.to_json
99
+ #=> "[{\"value\":\"divorced\",\"label\":\"Divorced\"},{\"value\":\"married\", ...
100
+ ```
93
101
 
94
- * You can retrieve a list with values for a group of enumeration constants.
102
+ * You can get an array of options, ready to use with the 'select',
103
+ 'select_tag', etc family of Rails helpers.
95
104
 
96
- ```ruby
97
- RelationshipStatus.values_for %w(MARRIED SINGLE)
98
- #=> [2, 1]
99
- ```
105
+ ```ruby
106
+ RelationshipStatus.to_a
107
+ #=> [['Divorced', 'divorced'], ['Married', 'married'], ['Single', 'single']]
108
+ ```
100
109
 
101
- * You can retrieve the value for a specific enumeration constant:
110
+ * You can retrieve a list with values for a group of enumeration constants.
102
111
 
103
- ```ruby
104
- RelationshipStatus.value_for("MARRIED")
105
- #=> 2
106
- ```
112
+ ```ruby
113
+ RelationshipStatus.values_for %w(MARRIED SINGLE)
114
+ #=> ['married', 'single']
115
+ ```
107
116
 
108
- * You can retrieve the symbol used to declare a specific enumeration value:
117
+ * You can retrieve the value for a specific enumeration constant:
109
118
 
110
- ```ruby
111
- RelationshipStatus.key_for(RelationshipStatus::MARRIED)
112
- #=> :married
113
- ```
119
+ ```ruby
120
+ RelationshipStatus.value_for('MARRIED')
121
+ #=> 'married'
122
+ ```
114
123
 
115
- * You can iterate over the list of the enumeration's values:
124
+ * You can retrieve the symbol used to declare a specific enumeration value:
116
125
 
117
- ```ruby
118
- RelationshipStatus.each_value { |value| ... }
119
- ```
126
+ ```ruby
127
+ RelationshipStatus.key_for(RelationshipStatus::MARRIED)
128
+ #=> :married
129
+ ```
120
130
 
121
- * You can iterate over the list of the enumeration's translations:
131
+ * You can iterate over the list of the enumeration's values:
122
132
 
123
- ```ruby
124
- RelationshipStatus.each_translation { |translation| ... }
125
- ```
133
+ ```ruby
134
+ RelationshipStatus.each_value { |value| ... }
135
+ ```
126
136
 
127
- * You can also retrieve all the translations of the enumeration:
137
+ * You can iterate over the list of the enumeration's translations:
128
138
 
129
- ```ruby
130
- RelationshipStatus.translations
131
- ```
139
+ ```ruby
140
+ RelationshipStatus.each_translation { |translation| ... }
141
+ ```
132
142
 
133
- * You can ask for the enumeration's length:
143
+ * You can also retrieve all the translations of the enumeration:
134
144
 
135
- ```ruby
136
- RelationshipStatus.length
137
- #=> 4
138
- ```
145
+ ```ruby
146
+ RelationshipStatus.translations
147
+ ```
139
148
 
140
- * You can manipulate the hash used to create the enumeration:
149
+ * You can ask for the enumeration's length:
141
150
 
142
- ```ruby
143
- RelationshipStatus.enumeration
144
- #=> returns the exact hash used to define the enumeration
145
- ```
151
+ ```ruby
152
+ RelationshipStatus.length
153
+ #=> 3
154
+ ```
146
155
 
147
- You can also create enumerations in the following ways:
156
+ ### Sorting enumerations
148
157
 
149
- * Passing an array of symbols, so that the respective value for each symbol
150
- will be the stringified version of the symbol itself:
151
-
152
- ```ruby
153
- class RelationshipStatus < EnumerateIt::Base
154
- associate_values :married, :single
155
- end
156
-
157
- RelationshipStatus::MARRIED
158
- #=> "married"
159
- ```
160
-
161
- * Passing hashes where the value for each key/pair does not include a
162
- translation. In this case, the I18n feature will be used (more on this
163
- below):
164
-
165
- ```ruby
166
- class RelationshipStatus < EnumerateIt::Base
167
- associate_values married: 1, single: 2
168
- end
169
- ```
170
-
171
- ### Defining a default sort mode
172
-
173
- When calling methods like `to_a`, `to_json` and `list`, the returned values
174
- will be sorted using the translation for each one of the enumeration values.
175
- If you want to overwrite the default sort mode, you can use the `sort_by` class
176
- method.
158
+ When calling methods like `to_a`, `to_json` and `list`, the returned values will be sorted using
159
+ the translation for each one of the enumeration values. If you want to overwrite the default sort
160
+ mode, you can use the `sort_by` class method.
177
161
 
178
162
  ```ruby
179
163
  class RelationshipStatus < EnumerateIt::Base
180
164
  associate_values married: 1, single: 2
181
165
 
182
- sort_by :value
166
+ sort_by :translation
183
167
  end
184
168
  ```
185
169
 
186
170
  The `sort_by` methods accept one of the following values:
187
171
 
188
- * `:translation`: The default behavior, will sort the returned values based 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 enumeration option.
191
- * `:none`: Will return values in order that was passed to associate_values call.
172
+ | Value | Behavior |
173
+ | :------------- | :------------------------------------------------------------------------------------------- |
174
+ | `:none` | The default behavior, will return values in order that was passed to `associate_values` call |
175
+ | `:translation` | will sort the returned values based on translations |
176
+ | `:name` | Will sort the returned values based on the name of each enumeration option |
192
177
 
193
178
  ## Using enumerations
194
179
 
195
- The cool part is that you can use these enumerations with any class, be it an
196
- ActiveRecord instance or not.
180
+ The cool part is that you can use these enumerations with any class, be it an `ActiveRecord`
181
+ instance or not.
197
182
 
198
183
  ```ruby
199
184
  class Person
200
185
  extend EnumerateIt
201
186
  attr_accessor :relationship_status
202
187
 
203
- has_enumeration_for :relationship_status, with: RelationshipStatus
188
+ has_enumeration_for :relationship_status
204
189
  end
205
190
  ```
206
191
 
207
- The `:with` option is not required. If you ommit it, EnumerateIt will try to
208
- load an enumeration class based on the camelized attribute name.
192
+ > **Note:** **EnumerateIt** will try to load an enumeration class based on the camelized attribute
193
+ > name. If you have a different name, you can specify it by using the `with` option:
194
+ >
195
+ > `has_enumeration_for :relationship_status, with: RelationshipStatus`
209
196
 
210
197
  This will create:
211
198
 
212
- * A humanized description for the values of the enumerated attribute:
213
-
214
- ```ruby
215
- p = Person.new
216
- p.relationship_status = RelationshipStatus::DIVORCED
217
- p.relationship_status_humanize
218
- #=> 'Divorced'
219
- ```
220
-
221
- * If you don't supply a humanized string to represent an option, EnumerateIt
222
- will use a 'humanized' version of the hash's key to humanize the
223
- attribute's value:
224
-
225
- ```ruby
226
- class RelationshipStatus < EnumerateIt::Base
227
- associate_values(
228
- married: 1,
229
- single: 2
230
- )
231
- end
199
+ * A "humanized" version of the hash's key to humanize the attribute's value:
232
200
 
233
- p = Person.new
234
- p.relationship_status = RelationshipStatus::MARRIED
235
- p.relationship_status_humanize
236
- #=> 'Married'
237
- ```
201
+ ```ruby
202
+ p = Person.new
203
+ p.relationship_status = RelationshipStatus::DIVORCED
204
+ p.relationship_status_humanize
205
+ #=> 'Divorced'
206
+ ```
238
207
 
239
- * The associated enumerations can be retrieved with the 'enumerations' class
240
- method.
208
+ * A translation for your options, if you include a locale to represent it
209
+ (see more in the [#i18n](I18n section):
241
210
 
242
- ```ruby
243
- Person.enumerations[:relationship_status]
244
- #=> RelationshipStatus
245
- ```
211
+ ```ruby
212
+ p = Person.new
213
+ p.relationship_status = RelationshipStatus::DIVORCED
214
+ p.relationship_status_humanize
215
+ #=> 'Divorciado'
216
+ ```
246
217
 
247
- * If you pass the `:create_helpers` option as `true`, it will create a helper
248
- method for each enumeration option (this option defaults to false):
218
+ * The associated enumerations, which can be retrieved with the `enumerations` class method:
249
219
 
250
- ```ruby
251
- class Person < ActiveRecord::Base
252
- has_enumeration_for :relationship_status, with: RelationshipStatus, create_helpers: true
253
- end
220
+ ```ruby
221
+ Person.enumerations
222
+ #=> { relationship_status: RelationshipStatus }
223
+ ```
254
224
 
255
- p = Person.new
256
- p.relationship_status = RelationshipStatus::MARRIED
225
+ * A helper method for each enumeration option, if you pass the `create_helpers` option as `true`:
257
226
 
258
- p.married?
259
- #=> true
227
+ ```ruby
228
+ class Person < ActiveRecord::Base
229
+ has_enumeration_for :relationship_status, with: RelationshipStatus, create_helpers: true
230
+ end
260
231
 
261
- p.divorced?
262
- #=> false
263
- ```
232
+ p = Person.new
233
+ p.relationship_status = RelationshipStatus::MARRIED
264
234
 
265
- * It's also possible to "namespace" the created helper methods, passing a
266
- hash to the `:create_helpers` option. This can be useful when two or more of
267
- the enumerations used share the same constants.
235
+ p.married?
236
+ #=> true
268
237
 
269
- ```ruby
270
- class Person < ActiveRecord::Base
271
- has_enumeration_for :relationship_status, with: RelationshipStatus,
272
- create_helpers: { prefix: true }
273
- end
238
+ p.divorced?
239
+ #=> false
240
+ ```
274
241
 
275
- p = Person.new
276
- p.relationship_status = RelationshipStatus::MARRIED
242
+ It's also possible to "namespace" the created helper methods, passing a hash to the `create_helpers`
243
+ option. This can be useful when two or more of the enumerations used share the same constants:
277
244
 
278
- p.relationship_status_married?
279
- #=> true
245
+ ```ruby
246
+ class Person < ActiveRecord::Base
247
+ has_enumeration_for :relationship_status,
248
+ with: RelationshipStatus, create_helpers: { prefix: true }
249
+ end
280
250
 
281
- p.relationship_status_divoced?
282
- #=> false
283
- ```
251
+ p = Person.new
252
+ p.relationship_status = RelationshipStatus::MARRIED
284
253
 
285
- * You can define polymorphic behavior for the enum values, so you can define
286
- a class for each of them:
254
+ p.relationship_status_married?
255
+ #=> true
287
256
 
288
- ```ruby
289
- class RelationshipStatus < EnumerateIt::Base
290
- associate_values :married, :single
257
+ p.relationship_status_divoced?
258
+ #=> false
259
+ ```
291
260
 
292
- class Married
293
- def saturday_night
294
- "At home with the kids"
295
- end
296
- end
261
+ You can define polymorphic behavior for the enumeration values, so you can define a class for each
262
+ of them:
297
263
 
298
- class Single
299
- def saturday_night
300
- "Party Hard!"
301
- end
264
+ ```ruby
265
+ class RelationshipStatus < EnumerateIt::Base
266
+ associate_values :married, :single
267
+
268
+ class Married
269
+ def saturday_night
270
+ 'At home with the kids'
302
271
  end
303
272
  end
304
273
 
305
- class Person < ActiveRecord::Base
306
- has_enumeration_for :relationship_status, with: RelationshipStatus,
307
- create_helpers: { polymorphic: true }
274
+ class Single
275
+ def saturday_night
276
+ 'Party Hard!'
277
+ end
308
278
  end
279
+ end
280
+
281
+ class Person < ActiveRecord::Base
282
+ has_enumeration_for :relationship_status,
283
+ with: RelationshipStatus, create_helpers: { polymorphic: true }
284
+ end
309
285
 
310
- p = Person.new
311
- p.relationship_status = RelationshipStatus::MARRIED
312
- p.relationship_status_object.saturday_night
313
- #=> "At home with the kids"
286
+ p = Person.new
287
+ p.relationship_status = RelationshipStatus::MARRIED
288
+ p.relationship_status_object.saturday_night
289
+ #=> 'At home with the kids'
314
290
 
315
- p.relationship_status = RelationshipStatus::SINGLE
316
- p.relationship_status_object.saturday_night
317
- #=> "Party Hard!"
318
- ```
291
+ p.relationship_status = RelationshipStatus::SINGLE
292
+ p.relationship_status_object.saturday_night
293
+ #=> 'Party Hard!'
294
+ ```
319
295
 
320
- You can also change the suffix '_object', using the `:suffix` option:
296
+ You can also change the suffix `_object`, using the `suffix` option:
321
297
 
322
- ```ruby
323
- class Person < ActiveRecord::Base
324
- has_enumeration_for :relationship_status, with: RelationshipStatus,
325
- create_helpers: { polymorphic: { suffix: '_mode' } }
326
- end
298
+ ```ruby
299
+ class Person < ActiveRecord::Base
300
+ has_enumeration_for :relationship_status,
301
+ with: RelationshipStatus, create_helpers: { polymorphic: { suffix: '_mode' } }
302
+ end
327
303
 
328
- p.relationship_status_mode.saturday_night
329
- ```
304
+ p.relationship_status_mode.saturday_night
305
+ ```
330
306
 
331
- * The `:create_helpers` also creates some mutator helper methods, that can be
332
- used to change the attribute's value.
307
+ The `create_helpers` also creates some mutator helper methods, that can be used to change the
308
+ attribute's value.
333
309
 
334
- ```ruby
335
- class Person < ActiveRecord::Base
336
- has_enumeration_for :relationship_status, with: RelationshipStatus, create_helpers: true
337
- end
310
+ ```ruby
311
+ p = Person.new
312
+ p.married!
338
313
 
339
- p = Person.new
340
- p.married!
314
+ p.married?
315
+ #=> true
316
+ ```
341
317
 
342
- p.married?
343
- #=> true
318
+ * A scope method for each enumeration option if you pass the `create_scopes` option as `true`:
344
319
 
345
- p.divorced?
346
- #=> false
347
- ```
320
+ ```ruby
321
+ class Person < ActiveRecord::Base
322
+ has_enumeration_for :relationship_status, with: RelationshipStatus, create_scopes: true
323
+ end
348
324
 
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):
325
+ Person.married.to_sql
326
+ #=> SELECT "users".* FROM "users" WHERE "users"."relationship_status" = "married"
327
+ ```
351
328
 
352
- ```ruby
353
- class Person < ActiveRecord::Base
354
- has_enumeration_for :relationship_status, with: RelationshipStatus, create_scopes: true
355
- end
329
+ The `:create_scopes` also accepts :prefix option.
356
330
 
357
- Person.married.to_sql
358
- #=> SELECT "people".* FROM "people" WHERE "people"."relationship_status" = 1
359
- ```
331
+ ```ruby
332
+ class Person < ActiveRecord::Base
333
+ has_enumeration_for :relationship_status,
334
+ with: RelationshipStatus, create_scopes: { prefix: true }
335
+ end
360
336
 
361
- The `:create_scopes` also accepts :prefix option.
337
+ Person.relationship_status_married.to_sql
338
+ ```
362
339
 
363
- ```ruby
364
- class Person < ActiveRecord::Base
365
- has_enumeration_for :relationship_status, with: RelationshipStatus,
366
- create_scopes: { prefix: true }
367
- end
340
+ * An inclustion validation (if your class can manage validations and responds to
341
+ `validates_inclusion_of`):
368
342
 
369
- Person.relationship_status_married.to_sql
370
- ```
343
+ ```ruby
344
+ class Person < ActiveRecord::Base
345
+ has_enumeration_for :relationship_status, with: RelationshipStatus
346
+ end
371
347
 
372
- * If your class can manage validations and responds to
373
- :validates_inclusion_of, it will create this validation:
348
+ p = Person.new(relationship_status: 'invalid')
349
+ p.valid?
350
+ #=> false
351
+ p.errors[:relationship_status]
352
+ #=> 'is not included in the list'
353
+ ```
374
354
 
375
- ```ruby
376
- class Person < ActiveRecord::Base
377
- has_enumeration_for :relationship_status, with: RelationshipStatus
378
- end
355
+ * An presence validation (if your class can manage validations and responds to
356
+ `validates_presence_of` and you pass the `required` options as `true`):
379
357
 
380
- p = Person.new(relationship_status: 6) # there is no '6' value in the enumeration
381
- p.valid?
382
- #=> false
383
- p.errors[:relationship_status]
384
- #=> "is not included in the list"
385
- ```
358
+ ```ruby
359
+ class Person < ActiveRecord::Base
360
+ has_enumeration_for :relationship_status, required: true
361
+ end
386
362
 
387
- * If your class can manage validations and responds to
388
- `:validates_presence_of`, you can pass the :required options as true and
389
- this validation will be created for you (this option defaults to false):
363
+ p = Person.new relationship_status: nil
364
+ p.valid?
365
+ #=> false
366
+ p.errors[:relationship_status]
367
+ #=> "can't be blank"
368
+ ```
390
369
 
391
- ```ruby
392
- class Person < ActiveRecord::Base
393
- has_enumeration_for :relationship_status, required: true
394
- end
370
+ If you pass the `skip_validation` option as `true`, it will not create any validations:
395
371
 
396
- p = Person.new relationship_status: nil
397
- p.valid?
398
- #=> false
399
- p.errors[:relationship_status]
400
- #=> "can't be blank"
401
- ```
372
+ ```ruby
373
+ class Person < ActiveRecord::Base
374
+ has_enumeration_for :relationship_status, with: RelationshipStatus, skip_validation: true
375
+ end
402
376
 
403
- * If you pass the `:skip_validation` option as `true`, it will not create any validations:
377
+ p = Person.new(relationship_status: 'invalid')
378
+ p.valid?
379
+ #=> true
380
+ ```
404
381
 
405
- ```ruby
406
- class Person < ActiveRecord::Base
407
- has_enumeration_for :relationship_status, with: RelationshipStatus, skip_validation: true
408
- end
382
+ Remember that you can add validations to any kind of class and not only to those derived from
383
+ `ActiveRecord::Base`.
409
384
 
410
- p = Person.new(relationship_status: 1_000_000)
411
- p.valid?
412
- #=> true
413
- ```
385
+ ### Why to define enumerations outside the class that uses them?
414
386
 
415
- Remember that you can add validations to any kind of class and not only to
416
- those derived from ActiveRecord::Base.
387
+ * It's clearer.
388
+ * You can add behaviour to the enumeration class.
389
+ * You can reuse the enumeration inside other classes.
417
390
 
418
391
  ## I18n
419
392
 
420
- I18n lookup is provided on both `_humanized` and `Enumeration#to_a` methods,
421
- given the hash key is a Symbol. The I18n strings are located on
422
- `enumerations.<enumeration_name>.<key>`:
393
+ I18n lookup is provided on both `_humanized` and `Enumeration#to_a` methods, given the hash key is
394
+ a Symbol. The I18n strings are located on `enumerations.<enumeration_name>.<key>`:
423
395
 
424
396
  ```yaml
425
397
  # Your locale file
426
- pt:
398
+ pt-BR:
427
399
  enumerations:
428
400
  relationship_status:
429
401
  married: Casado
@@ -432,9 +404,8 @@ pt:
432
404
  ```ruby
433
405
  class RelationshipStatus < EnumerateIt::Base
434
406
  associate_values(
435
- married: 1,
436
- single: 2,
437
- divorced: [3, "He's divorced"]
407
+ :married,
408
+ :single
438
409
  )
439
410
  end
440
411
 
@@ -444,79 +415,95 @@ p.relationship_status_humanize
444
415
  #=> 'Casado'
445
416
 
446
417
  p.relationship_status = RelationshipStatus::SINGLE
447
- p.relationship_status_humanize # nonexistent key
418
+ p.relationship_status_humanize # Non-existent key
448
419
  #=> 'Single'
449
-
450
- p.relationship_status = RelationshipStatus::DIVORCED
451
- p.relationship_status_humanize # uses the provided string
452
- #=> 'He's divorced'
453
420
  ```
454
421
 
455
422
  You can also translate specific values:
456
423
 
457
424
  ```ruby
458
- RelationshipStatus.t(1)
425
+ status = RelationshipStatus::MARRIED
426
+ RelationshipStatus.t(status)
459
427
  #=> 'Casado'
460
428
  ```
461
429
 
462
- ## Installation
430
+ ## Using enumerations to handle a legacy database
463
431
 
464
- ```bash
465
- gem install enumerate_it
466
- ```
432
+ **EnumerateIt** can help you to build a Rails application around a legacy database which was filled
433
+ with those small and unchangeable tables used to create foreign key constraints everywhere, like the
434
+ following example:
467
435
 
468
- ## Using with Rails
436
+ ```sql
437
+ Table "public.relationship_status"
469
438
 
470
- * Add the gem to your Gemfile:
439
+ Column | Type | Modifiers
440
+ -------------+---------------+-----------
441
+ code | character(1) | not null
442
+ description | character(11) |
471
443
 
472
- ```ruby
473
- gem 'enumerate_it'
474
- ```
444
+ Indexes:
445
+ "relationship_status_pkey" PRIMARY KEY, btree (code)
475
446
 
476
- * Run the install generator:
447
+ SELECT * FROM relationship_status;
477
448
 
478
- ```bash
479
- rails generate enumerate_it:install
480
- ```
449
+ code | description
450
+ ---- +--------------
451
+ 1 | Single
452
+ 2 | Married
453
+ 3 | Divorced
454
+ ```
481
455
 
482
- An interesting approach to use it in Rails apps is to create an
483
- `app/enumerations` folder.
456
+ You might also have something like a `users` table with a `relationship_status` column and a foreign
457
+ key pointing to the `relationship_status` table.
484
458
 
485
- There is also a Rails Generator that you can use to generate enumerations and
486
- their locale files. Take a look at how to use it running:
459
+ While this is a good thing from the database normalization perspective, managing these values in
460
+ tests is very hard. Doing database joins just to get the description of some value is absurd.
461
+ And, more than this, referencing them in the code using magic numbers was terrible and meaningless:
462
+ What does it mean when we say that someone or something is `2`?
487
463
 
488
- ```bash
489
- rails generate enumerate_it:enum --help
464
+ In this case, you can pass a hash:
465
+
466
+ ```ruby
467
+ class RelationshipStatus < EnumerateIt::Base
468
+ associate_values(
469
+ single: 1,
470
+ married: 2,
471
+ divorced: 3
472
+ )
473
+ end
490
474
  ```
491
475
 
492
- ## Supported Ruby and Rails versions
476
+ ```ruby
477
+ RelationshipStatus::MARRIED
478
+ #=> 2
479
+ ```
493
480
 
494
- Check [travis config file](https://github.com/lucascaton/enumerate_it/blob/master/.travis.yml).
481
+ You can also sort it by its value: `sort_by :value`.
495
482
 
496
- ## Why did you reinvent the wheel?
483
+ ## FAQ
497
484
 
498
- There are other similar solutions to the problem out there, but I could not
499
- find one that worked both with strings and integers as the enumerations'
500
- codes. I had both situations in my legacy database.
485
+ #### What versions of Ruby and Rails are supported?
501
486
 
502
- ## Why defining enumerations outside the class that use it?
487
+ Please check out [travis config file](https://github.com/lucascaton/enumerate_it/blob/master/.travis.yml).
503
488
 
504
- * I think it's cleaner.
505
- * You can add behaviour to the enumeration class.
506
- * You can reuse the enumeration inside other classes.
489
+ #### Can I set a value to always be at the end of a sorted list?
490
+
491
+ Yes, please see [issue #60](https://github.com/lucascaton/enumerate_it/issues/60).
492
+
493
+ ## Changelog
494
+
495
+ Changes are maintained under [Releases](https://github.com/lucascaton/enumerate_it/releases).
507
496
 
508
497
  ## Note on Patches/Pull Requests
509
498
 
510
- * Fork the project.
511
- * Make your feature addition or bug fix.
512
- * Add tests for it. This is important so I don't break it in a future
513
- version unintentionally.
514
- * Run the tests agaist all supported versions: `$ rake`.
515
- * Commit, do not mess with Rakefile, version, or history. (if you want to
516
- have your own version, that is fine but bump version in a commit by itself
517
- I can ignore when I pull)
518
- * Send me a pull request. Bonus points for topic branches.
499
+ * Fork the project.
500
+ * Make your feature addition or bug fix.
501
+ * Add tests for it. This is important so we don't break it in a future version unintentionally.
502
+ * [Optional] Run the tests agaist a specific Gemfile: `$ appraisal rails_5.0 rake spec`.
503
+ * Run the tests agaist all supported versions: `$ rake`.
504
+ * Commit, but please do not mess with `Rakefile`, version, or history.
505
+ * Send a Pull Request. Bonus points for topic branches.
519
506
 
520
507
  ## Copyright
521
508
 
522
- Copyright (c) 2010-2016 Cássio Marques and Lucas Caton. See LICENSE for details.
509
+ Copyright (c) 2010-2016 Cássio Marques and Lucas Caton. See `LICENSE` file for details.
data/enumerate_it.png ADDED
Binary file
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 3.0.9"
6
6
  gem "activerecord", "~> 3.0.9"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 3.1.9"
6
6
  gem "activerecord", "~> 3.1.9"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 3.2.9"
6
6
  gem "activerecord", "~> 3.2.9"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 4.0.9"
6
6
  gem "activerecord", "~> 4.0.9"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 4.1.9"
6
6
  gem "activerecord", "~> 4.1.9"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 4.2.7.1"
6
6
  gem "activerecord", "~> 4.2.7.1"
@@ -1,6 +1,6 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "activesupport", "~> 5.0.0.1"
6
6
  gem "activerecord", "~> 5.0.0.1"
@@ -93,7 +93,7 @@ module EnumerateIt
93
93
  private
94
94
 
95
95
  def sorted_map
96
- return enumeration if sort_mode == :none
96
+ return enumeration if sort_mode.nil? || sort_mode == :none
97
97
 
98
98
  enumeration.sort_by { |k, v| sort_lambda.call(k, v) }
99
99
  end
@@ -103,7 +103,7 @@ module EnumerateIt
103
103
  value: ->(_k, v) { v[0] },
104
104
  name: ->(k, _v) { k },
105
105
  translation: ->(_k, v) { translate(v[1]) }
106
- }[sort_mode || :translation]
106
+ }[sort_mode]
107
107
  end
108
108
 
109
109
  def normalize_enumeration(values_hash)
@@ -1,3 +1,3 @@
1
1
  module EnumerateIt
2
- VERSION = '1.3.1'.freeze
2
+ VERSION = '1.4.0.rc1'.freeze
3
3
  end
@@ -7,7 +7,7 @@ module EnumerateIt
7
7
 
8
8
  class_option :singular, type: 'string', desc: 'Singular name for i18n'
9
9
 
10
- class_option :lang, type: 'string', desc: 'Lang to use in i18n', default: 'en'
10
+ class_option :lang, type: 'string', desc: 'Language to use in i18n', default: 'en'
11
11
 
12
12
  desc 'Creates a locale file on config/locales'
13
13
  def create_locale
@@ -198,7 +198,7 @@ describe EnumerateIt::Base do
198
198
 
199
199
  context 'associate values with a list' do
200
200
  it 'creates constants for each enumeration value' do
201
- expect(TestEnumerationWithList::FIRST).to eq('first')
201
+ expect(TestEnumerationWithList::FIRST).to eq('first')
202
202
  expect(TestEnumerationWithList::SECOND).to eq('second')
203
203
  end
204
204
 
@@ -207,7 +207,15 @@ describe EnumerateIt::Base do
207
207
  end
208
208
  end
209
209
 
210
- context 'specifying a default sort mode' do
210
+ context 'not specifying a sort mode' do
211
+ subject { create_enumeration_class_with_sort_mode(nil).to_a }
212
+
213
+ it 'does not sort' do
214
+ is_expected.to eq([%w(xyz 1), %w(fgh 2), %w(abc 3), %w(jkl 0)])
215
+ end
216
+ end
217
+
218
+ context 'specifying a sort mode' do
211
219
  subject { create_enumeration_class_with_sort_mode(sort_mode).to_a }
212
220
 
213
221
  context 'by value' do
@@ -7,17 +7,12 @@ class TestEnumeration < EnumerateIt::Base
7
7
  end
8
8
 
9
9
  class TestEnumerationWithoutArray < EnumerateIt::Base
10
- associate_values(
11
- value_one: '1',
12
- value_two: '2'
13
- )
10
+ associate_values value_one: '1', value_two: '2'
14
11
  end
15
12
 
16
13
  class TestEnumerationWithExtendedBehaviour < EnumerateIt::Base
17
- associate_values(
18
- first: '1',
19
- second: '2'
20
- )
14
+ associate_values first: '1', second: '2'
15
+
21
16
  def self.to_a
22
17
  super.reverse
23
18
  end
@@ -32,21 +27,15 @@ class TestEnumerationWithReservedWords < EnumerateIt::Base
32
27
  end
33
28
 
34
29
  class TestEnumerationWithDash < EnumerateIt::Base
35
- associate_values(
36
- 'pt-BR'
37
- )
30
+ associate_values 'pt-BR'
38
31
  end
39
32
 
40
33
  class TestEnumerationWithCamelCase < EnumerateIt::Base
41
- associate_values(
42
- 'iPhone'
43
- )
34
+ associate_values 'iPhone'
44
35
  end
45
36
 
46
37
  class Foobar < EnumerateIt::Base
47
- associate_values(
48
- bar: 'foo'
49
- )
38
+ associate_values bar: 'foo'
50
39
  end
51
40
 
52
41
  class PolymorphicEnum < EnumerateIt::Base
@@ -67,12 +56,13 @@ end
67
56
 
68
57
  class BaseClass
69
58
  extend EnumerateIt
59
+
70
60
  has_enumeration_for :foobar, with: TestEnumeration
71
61
  end
72
62
 
73
63
  def create_enumeration_class_with_sort_mode(sort_mode)
74
64
  Class.new(EnumerateIt::Base) do
75
- sort_by sort_mode
65
+ sort_by(sort_mode)
76
66
 
77
67
  associate_values(
78
68
  foo: %w(1 xyz),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumerate_it
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cássio Marques
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-08-28 00:00:00.000000000 Z
12
+ date: 2016-10-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -142,6 +142,7 @@ files:
142
142
  - README.md
143
143
  - Rakefile
144
144
  - enumerate_it.gemspec
145
+ - enumerate_it.png
145
146
  - gemfiles/rails_3.0.gemfile
146
147
  - gemfiles/rails_3.1.gemfile
147
148
  - gemfiles/rails_3.2.gemfile
@@ -180,12 +181,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
181
  version: 1.9.3
181
182
  required_rubygems_version: !ruby/object:Gem::Requirement
182
183
  requirements:
183
- - - ">="
184
+ - - ">"
184
185
  - !ruby/object:Gem::Version
185
- version: '0'
186
+ version: 1.3.1
186
187
  requirements: []
187
188
  rubyforge_project:
188
- rubygems_version: 2.6.6
189
+ rubygems_version: 2.5.1
189
190
  signing_key:
190
191
  specification_version: 4
191
192
  summary: Ruby Enumerations