enumerate_it 1.3.1 → 1.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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