enumerate_it 1.2.8 → 1.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -9,4 +9,4 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
9
9
  spec.pattern = FileList['spec/**/*_spec.rb']
10
10
  end
11
11
 
12
- task :default => :spec
12
+ task default: :spec
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../lib/enumerate_it/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ['Cássio Marques', 'Lucas Caton']
5
+ gem.description = 'Enumerations for Ruby with some magic powers!'
6
+ gem.summary = 'Ruby Enumerations'
7
+ gem.homepage = 'https://github.com/lucascaton/enumerate_it'
8
+
9
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.test_files = `git ls-files -- spec/*`.split("\n")
12
+ gem.name = 'enumerate_it'
13
+ gem.require_paths = ['lib']
14
+ gem.version = EnumerateIt::VERSION
15
+
16
+ gem.add_dependency 'activesupport', '>= 3.0.0'
17
+
18
+ gem.add_development_dependency 'appraisal'
19
+ gem.add_development_dependency 'pry'
20
+ gem.add_development_dependency 'rake'
21
+ gem.add_development_dependency 'rspec', '~> 2.14.1'
22
+ end
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.0.0"
6
+ gem "activerecord", "~> 3.0.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.1.0"
6
+ gem "activerecord", "~> 3.1.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.2.0"
6
+ gem "activerecord", "~> 3.2.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.0.0"
6
+ gem "activerecord", "~> 4.0.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.1.0"
6
+ gem "activerecord", "~> 4.1.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.2.0"
6
+ gem "activerecord", "~> 4.2.0"
7
+
8
+ gemspec :path => "../"
@@ -1,276 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
- # EnumerateIt - Ruby Enumerations
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
- # And then I had things like a people table with a 'relationship_status' column with a foreign key
32
- # pointing to the relationshipstatus table.
33
- #
34
- # While this is a good thing from the database normalization perspective, managing this values in
35
- # my tests was very hard. More than this, referencing them in my code using magic numbers was terrible
36
- # and meaningless: What's does it mean when we say that someone or something is '2'?
37
- #
38
- # Enter EnumerateIt.
39
- #
40
- # = Creating enumerations
41
- #
42
- # Enumerations are created as models, but you can put then anywhere in your application. In Rails
43
- # applications, I put them inside models/.
44
- #
45
- # class RelationshipStatus < EnumerateIt::Base
46
- # associate_values(
47
- # :single => [1, 'Single'],
48
- # :married => [2, 'Married'],
49
- # :widow => [3, 'Widow'],
50
- # :divorced => [4, 'Divorced'],
51
- # )
52
- # end
53
- #
54
- # This will create some nice stuff:
55
- #
56
- # - Each enumeration's value will turn into a constant:
57
- #
58
- # RelationshipsStatus::SINGLE # returns 1
59
- # RelationshipStatus::MARRIED # returns 2 and so on...
60
- #
61
- # - You can retrieve a list with all the enumeration codes:
62
- #
63
- # RelationshipStatus.list # [1,2,3,4]
64
- #
65
- # You can get an array of options, ready to use with the 'select', 'select_tag', etc family of Rails helpers.
66
- #
67
- # RelationshipStatus.to_a # [["Divorced", 4],["Married", 2],["Single", 1],["Widow", 3]]
68
- #
69
- # You can retrive a list with values for a group of enumeration constants
70
- #
71
- # RelationshipStatus.values_for %w(MARRIED SINGLE) # [2, 1]
72
- #
73
- # You can retrieve the value for a specific enumeration constant:
74
- #
75
- # RelationshipStatus.value_for("MARRIED") # 2
76
- #
77
- # You can iterate over the list of the enumeration's values:
78
- #
79
- # RelationshipStatus.each_value { |value| # ... }
80
- #
81
- # You can iterate over the list of the enumeration's translations:
82
- #
83
- # RelationshipStatus.each_translation { |translation| # ... }
84
- #
85
- # You can retrieve the symbol used to declare a specific enumeration value:
86
- #
87
- # RelationshipStatus.key_for(RelationshioStatus::MARRIED) # :married
88
- #
89
- # - You can manipulate the hash used to create the enumeration:
90
- #
91
- # RelationshipStatus.enumeration # returns the exact hash used to define the enumeration
92
- #
93
- # You can also create enumerations in the following ways:
94
- #
95
- # * Passing an array of symbols, so that the respective value for each symbol will be the stringified version of the symbol itself:
96
- #
97
- # class RelationshipStatus < EnumerateIt::Base
98
- # associate_values :married, :single
99
- # end
100
- #
101
- # RelationshipStatus::MARRIED # returns "married" and so on
102
- #
103
- # * 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):
104
- #
105
- # class RelationshipStatus < EnumerateIt::Base
106
- # associate_values :married => 1, :single => 2
107
- # end
108
- #
109
- # = Using enumerations
110
- #
111
- # The cool part is that you can use these enumerations with any class, be it an ActiveRecord instance
112
- # or not.
113
- #
114
- # class Person
115
- # extend EnumerateIt
116
- # attr_accessor :relationship_status
117
- #
118
- # has_enumeration_for :relationship_status, :with => RelationshipStatus
119
- # end
120
- #
121
- # The :with option is not required. If you ommit it, EnumerateIt will try to load an
122
- # enumeration class based on the camelized attribute name.
123
- #
124
- # This will create:
125
- #
126
- # - A humanized description for the values of the enumerated attribute:
127
- #
128
- # p = Person.new
129
- # p.relationship_status = RelationshipStatus::DIVORCED
130
- # p.relationship_status_humanize # => 'Divorced'
131
- #
132
- # - If you don't supply a humanized string to represent an option, EnumerateIt will use a 'humanized'
133
- # version of the hash's key to humanize the attribute's value
134
- #
135
- # class RelationshipStatus < EnumerateIt::Base
136
- # associate_values(
137
- # :married => 1,
138
- # :single => 2
139
- # )
140
- # end
141
- #
142
- # p = Person.new
143
- # p.relationship_status = RelationshipStatus::MARRIED
144
- # p.relationship_status_humanize # => 'Married'
145
- #
146
- # - The associated enumerations can be retrieved with the 'enumerations' class method.
147
- # Person.enumerations[:relationship_status] # => RelationshipStatus
148
- #
149
- # - If you pass the :create_helpers option as 'true', it will create a helper method for each enumeration
150
- # option (this option defaults to false):
151
- #
152
- # class Person < ActiveRecord::Base
153
- # has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => true
154
- # end
155
- #
156
- # p = Person.new
157
- # p.relationship_status = RelationshipStatus::MARRIED
158
- # p.married? #=> true
159
- # p.divorced? #=> false
160
- #
161
- # - It's also possible to "namespace" the created helper methods, passing a hash to the :create_helpers option.
162
- # This can be useful when two or more of the enumerations used share the same constants.
163
- #
164
- # class Person < ActiveRecord::Base
165
- # has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :prefix => true }
166
- # end
167
- #
168
- # p = Person.new
169
- # p.relationship_status = RelationshipStatus::MARRIED
170
- # p.relationship_status_married? #=> true
171
- # p.relationship_status_divoced? #=> false
172
- #
173
- # - You can define polymorphic behavior for the enum values, so you can define a class for each of
174
- # them:
175
- #
176
- # class RelationshipStatus < EnumerateIt::Base
177
- # associate_values :married, :single
178
- #
179
- # class Married
180
- # def saturday_night
181
- # "At home with the kids"
182
- # end
183
- # end
184
- #
185
- # class Single
186
- # def saturday_night
187
- # "Party Hard!"
188
- # end
189
- # end
190
- # end
191
- #
192
- # class Person < ActiveRecord::Base
193
- # has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => true }
194
- # end
195
- #
196
- # p = Person.new
197
- # p.relationship_status = RelationshipStatus::MARRIED
198
- # p.relationship_status_object.saturday_night # => "At home with the kids"
199
- #
200
- # p.relationship_status = RelationshipStatus::SINGLE
201
- # p.relationship_status_object.saturday_night # => "Party Hard!"
202
- #
203
- # You can also change the suffix '_object', using the :suffix option:
204
- #
205
- # class Person < ActiveRecord::Base
206
- # has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_helpers => { :polymorphic => { :suffix => "_mode" } }
207
- # end
208
- #
209
- # p.relationship_status_mode.saturday_night
210
- #
211
- # - If you pass the :create_scopes option as 'true', it will create a scope method for each enumeration option (this option defaults to false):
212
- #
213
- # class Person < ActiveRecord::Base
214
- # has_enumeration_for :relationship_status, :with => RelationshipStatus, :create_scopes => true
215
- # end
216
- #
217
- # Person.married.to_sql # => SELECT "people".* FROM "people" WHERE "people"."relationship_status" = 1
218
- #
219
- # NOTE: The :create_scopes option can only be used for Rails.version >= 3.0.0.
220
- #
221
- # - If your class can manage validations and responds to :validates_inclusion_of, it will create this
222
- # validation:
223
- #
224
- # class Person < ActiveRecord::Base
225
- # has_enumeration_for :relationship_status, :with => RelationshipStatus
226
- # end
227
- #
228
- # p = Person.new :relationship_status => 6 # => there is no '6' value in the enumeration
229
- # p.valid? # => false
230
- # p.errors[:relationship_status] # => "is not included in the list"
231
- #
232
- # - Also, if your class responds to :validates_presence_of, you can pass an :required option and this validation
233
- # will be added to your attribute:
234
- #
235
- # class Person < ActiveRecord::Base
236
- # has_enumeration_for :relationship_status, :required => true # => defaults to false
237
- # end
238
- #
239
- # Remember that in Rails 3 you can add validations to any kind of class and not only to those derived from
240
- # ActiveRecord::Base.
241
- #
242
- # = Using with Rails/ActiveRecord
243
- #
244
- # * Create an initializer with the following code:
245
- #
246
- # ActiveRecord::Base.extend EnumerateIt
247
- #
248
- # * Add the 'enumerate_it' gem as a dependency in your environment.rb (Rails 2.3.x) or Gemfile (if you're using Bundler)
249
- #
250
- # = Why did you reinvent the wheel?
251
- #
252
- # There are other similar solutions to the problem out there, but I could not find one that
253
- # worked both with strings and integers as the enumerations' codes. I had both situations in
254
- # my legacy database.
255
- #
256
- # = Why defining enumerations outside the class that used it?
257
- #
258
- # - I think it's cleaner.
259
- # - You can add behaviour to the enumeration class.
260
- # - You can reuse the enumeration inside other classes.
261
- #
262
-
263
- require "active_support/core_ext/class/attribute"
264
- require "enumerate_it/base"
265
- require "enumerate_it/class_methods"
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'enumerate_it/base'
5
+ require 'enumerate_it/class_methods'
266
6
 
267
7
  module EnumerateIt
268
8
  def self.extended(receiver)
269
- receiver.class_attribute :enumerations, :instance_writer => false, :instance_reader => false
9
+ receiver.class_attribute :enumerations, instance_writer: false, instance_reader: false
270
10
  receiver.enumerations = {}
271
11
 
272
12
  receiver.extend ClassMethods
273
13
  end
274
14
  end
275
-
276
-
@@ -19,7 +19,7 @@ module EnumerateIt
19
19
  end
20
20
 
21
21
  def self.list
22
- enumeration.values.map { |value| value[0] }.sort
22
+ sorted_map.map { |_k, v| v.first }
23
23
  end
24
24
 
25
25
  def self.enumeration
@@ -85,6 +85,8 @@ module EnumerateIt
85
85
  private
86
86
 
87
87
  def self.sorted_map
88
+ return enumeration if sort_mode == :none
89
+
88
90
  enumeration.sort_by { |k, v| sort_lambda.call(k, v) }
89
91
  end
90
92
 
@@ -93,7 +95,6 @@ module EnumerateIt
93
95
  :value => lambda { |k, v| v[0] },
94
96
  :name => lambda { |k, v| k },
95
97
  :translation => lambda { |k, v| translate(v[1]) },
96
- :none => lambda { |k, v| nil }
97
98
  }[sort_mode || :translation]
98
99
  end
99
100
 
@@ -1,3 +1,3 @@
1
1
  module EnumerateIt
2
- VERSION = "1.2.8"
2
+ VERSION = '1.2.9'
3
3
  end
@@ -16,9 +16,39 @@ describe EnumerateIt::Base do
16
16
  TestEnumerationWithDash::PT_BR.should == 'pt-BR'
17
17
  end
18
18
 
19
- it "creates a method that returns the allowed values in the enumeration's class" do
20
- TestEnumeration.list.should == ['1', '2', '3']
21
- end
19
+ describe ".list" do
20
+ it "creates a method that returns the allowed values in the enumeration's class" do
21
+ TestEnumeration.list.should == ['1', '2', '3']
22
+ end
23
+
24
+ context "specifying a default sort mode" do
25
+ subject { create_enumeration_class_with_sort_mode(sort_mode).list }
26
+
27
+ context "by value" do
28
+ let(:sort_mode) { :value }
29
+
30
+ it { should == %w(0 1 2 3) }
31
+ end
32
+
33
+ context "by name" do
34
+ let(:sort_mode) { :name }
35
+
36
+ it { should == %w(2 1 3 0) }
37
+ end
38
+
39
+ context "by translation" do
40
+ let(:sort_mode) { :translation }
41
+
42
+ it { should == %w(3 2 0 1) }
43
+ end
44
+
45
+ context "by nothing" do
46
+ let(:sort_mode) { :none }
47
+
48
+ it { should == %w(1 2 3 0) }
49
+ end
50
+ end
51
+ end
22
52
 
23
53
  it "creates a method that returns the enumeration specification" do
24
54
  TestEnumeration.enumeration.should == {
@@ -207,7 +237,7 @@ describe EnumerateIt::Base do
207
237
  end
208
238
  end
209
239
 
210
- ActiveRecordStub.stub!(:validates_inclusion_of).and_return(true)
240
+ ActiveRecordStub.stub(:validates_inclusion_of).and_return(true)
211
241
  ActiveRecordStub.extend EnumerateIt
212
242
  end
213
243
 
@@ -220,7 +250,7 @@ describe EnumerateIt::Base do
220
250
 
221
251
  context "using the :required option" do
222
252
  before :each do
223
- ActiveRecordStub.stub!(:validates_presence_of).and_return(true)
253
+ ActiveRecordStub.stub(:validates_presence_of).and_return(true)
224
254
  end
225
255
 
226
256
  it "creates a validation for presence" do