enum_ext 0.1.8 → 0.2.0

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: 1a1510d12023a14d33c2e944a41354de1e7aee23
4
- data.tar.gz: 54ec02ec7bcc827fd6b3d5a731e8ba0ebe3f88a8
3
+ metadata.gz: ed6a02d91d85ab0c0580df99fc4747513053eef1
4
+ data.tar.gz: d66d1b253f9bd512c1eed331b980591b4c774222
5
5
  SHA512:
6
- metadata.gz: 797719321c75c6b9b9920075cbd7f18e60eab038cd3d92c16bbdb83f878044c7233f30869e491009926cae6b7fa79303d176abebe7854f58ab9101ebaaf53287
7
- data.tar.gz: 95558724f73fcd3311983c9f4932ebadb833d4b44056dea8110a0b1a4135c0ed1d9c84af02473afbf7d0c983d66f67de76a5e97b949039de946eeea6009f4816
6
+ metadata.gz: 14ac092e452730ef84fcc313877de7fb83254c35ca009ba032e9a1794bb3e391141b4f553c0aa7884e2b69d332feb1c94f06e2527a87ca434657562ec0a4de4c
7
+ data.tar.gz: 171c5a7736a49e9c592c3d92005b93c312610698cc0c7e7d60aed13e5a712eed9728629473aa41f1b1f1d4dd40fd72c4a84227561217051620dd463f64ae1055
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- enum_ext (0.1.7)
4
+ enum_ext (0.1.8)
5
5
  activerecord (>= 4.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -7,7 +7,7 @@ EnumExt extends rails enum adding localization template, mass-assign on scopes w
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'enum_ext'
10
+ gem 'enum_ext', '~> 0.2'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -24,7 +24,8 @@ Or install it yourself as:
24
24
  class SomeModel
25
25
  extend EnumExt
26
26
 
27
- localize_enum ...
27
+ humanize_enum ...
28
+ translate_enum ...
28
29
  ext_enum_sets ...
29
30
  mass_assign_enum ...
30
31
  end
@@ -43,15 +44,12 @@ Or install it yourself as:
43
44
 
44
45
  Now let's review some examples of possible enum extensions
45
46
 
46
- ### Localization (localize_enum)
47
+ ### Humanization (humanize_enum)
47
48
 
48
49
  class Request
49
50
  ...
50
51
  localize_enum :status, {
51
52
 
52
- #locale dependent example ( it dynamically use current locale ):
53
- in_cart: -> { I18n.t("request.status.in_cart") },
54
-
55
53
  #locale dependent example with internal pluralization and lambda:
56
54
  payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
57
55
 
@@ -81,10 +79,26 @@ If you need some substitution you can go like this:
81
79
  request.t_status % {date: Time.now.to_s} >> Delivered at: 05.02.2016
82
80
 
83
81
  If you need select status on form:
84
-
85
- f.select :status, Request.t_statuses.invert.to_a
82
+ f.select :status, Request.t_statuses_options
83
+
84
+ Works with ext_enum_sets, slicing t_enum_set from original set of enum values ( enum - status, set_name - delivery_set )
85
+
86
+ f.select :status, Request.t_delivery_set_statuses_options
86
87
 
87
- Works with ext_enum_sets, slicing t_enum_set from original set of enum values
88
+ ### Translate (translate_enum)
89
+
90
+ Enum is translated using scope 'active_record.attributes.class_name_underscore.enum', or the given one:\
91
+
92
+ translate_enum :status, 'active_record.request.enum'
93
+
94
+ Or it can be done with block either with translate or humanize:
95
+
96
+ translate_enum :status do
97
+ I18n.t( "active_record.request.enum.#{status}" )
98
+ end
99
+
100
+ Also since we place by default enum translation in same place as enum name translation
101
+ human_attribute_name is redefined so it will work fine in ActiveAdmin, but you need to add translation to locale.
88
102
 
89
103
  ### Enum to_i shortcut ( enum_i )
90
104
 
@@ -96,7 +110,6 @@ Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name]
96
110
  request.payed_i # 10
97
111
 
98
112
 
99
-
100
113
  ### Enum Sets (ext_enum_sets)
101
114
 
102
115
  **Use-case** For example you have pay bills of different types, and you want to group some types in debit and credit "super-types", and have scope PayBill.debit, instance method with question mark as usual enum does pay_bill.debit?.
@@ -147,6 +160,7 @@ You can call ext_enum_sets more than one time defining a superposition of alread
147
160
  outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... # any other array operations like &, + and so can be used
148
161
  }
149
162
 
163
+
150
164
  ### Mass-assign ( mass_assign_enum )
151
165
 
152
166
  Syntax sugar for mass-assigning enum values.
@@ -177,6 +191,7 @@ You can call ext_enum_sets more than one time defining a superposition of alread
177
191
  order.requests.delivered.count # >> N + M
178
192
 
179
193
 
194
+
180
195
  ####Rem:
181
196
 
182
197
  **mass_assign_enum** accepts additional options as last argument. Calling
@@ -1,3 +1,3 @@
1
1
  module EnumExt
2
- VERSION = "0.1.8"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/enum_ext.rb CHANGED
@@ -12,62 +12,6 @@ require "enum_ext/version"
12
12
  # end
13
13
  #
14
14
  module EnumExt
15
- # Ex using localize_enum with Request
16
- # class Request
17
- # ...
18
- # localize_enum :status, {
19
- #
20
- # #locale dependent example ( it dynamically use current locale ):
21
- # in_cart: -> { I18n.t("request.status.in_cart") },
22
-
23
- # #locale dependent example with pluralization and lambda:
24
- # payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
25
-
26
- # #locale dependent example with pluralization and proc:
27
- # payed: proc{ I18n.t("request.status.payed", count: self.sum ) }
28
- #
29
- # #locale independent:
30
- # ready_for_shipment: "Ready to go!"
31
- #
32
- #
33
- # }
34
- # end
35
-
36
- # Console:
37
- # request.sum = 3
38
- # request.payed!
39
- # request.status # >> payed
40
- # request.t_status # >> "Payed 3 dollars"
41
- # Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
42
-
43
- # if you need some substitution you can go like this
44
- # localize_enum :status, {
45
- # ..
46
- # delivered: "Delivered at: %{date}"
47
- # }
48
- # request.delivered!
49
- # request.t_status % {date: Time.now.to_s} # >> Delivered at: 05.02.2016
50
- #
51
- # Using in select:
52
- # f.select :status, Request.t_statuses.invert.to_a
53
- #
54
- def localize_enum( enum_name, localizations )
55
- self.instance_eval do
56
- define_singleton_method( "t_#{enum_name.to_s.pluralize}" ) do
57
- localizations.try(:with_indifferent_access) || localizations
58
- end
59
- define_method "t_#{enum_name}" do
60
- t = localizations.try(:with_indifferent_access)[send(enum_name)]
61
- if t.try(:lambda?)
62
- t.try(:arity) == 1 && t.call( self ) || t.try(:call)
63
- elsif t.is_a?(Proc)
64
- instance_eval(&t)
65
- else
66
- t
67
- end.to_s
68
- end
69
- end
70
- end
71
15
 
72
16
  def enum_i( enum_name )
73
17
  define_method "#{enum_name}_i" do
@@ -75,6 +19,7 @@ module EnumExt
75
19
  end
76
20
  end
77
21
 
22
+
78
23
  # Ex ext_enum_sets
79
24
  # This method intend for creating and using some sets of enum values with similar to original enum syntax
80
25
  # it creates: scopes for subsets like enum did, instance method with ? similar to enum methods, and methods like Request.statuses
@@ -120,18 +65,30 @@ module EnumExt
120
65
  options.each do |set_name, enum_vals|
121
66
  scope set_name, -> { where( enum_name => self.send( enum_name.to_s.pluralize ).slice( *enum_vals.map(&:to_s) ).values ) }
122
67
 
68
+
123
69
  define_singleton_method( "#{set_name}_#{enum_name.to_s.pluralize}" ) do
124
70
  enum_vals
125
71
  end
126
72
 
73
+ # set?
127
74
  define_method "#{set_name}?" do
128
75
  self.send(enum_name) && ( enum_vals.include?( self.send(enum_name) ) || enum_vals.include?( self.send(enum_name).to_sym ))
129
76
  end
130
77
 
78
+ # t_set_enums
131
79
  define_singleton_method( "t_#{set_name}_#{enum_name.to_s.pluralize}" ) do
132
- self.send( "t_#{enum_name.to_s.pluralize}" ).slice( *self.send("#{set_name}_#{enum_name.to_s.pluralize}") )
80
+ send( "t_#{enum_name.to_s.pluralize}" ).slice( *self.send("#{set_name}_#{enum_name.to_s.pluralize}") )
133
81
  end
134
82
 
83
+ # t_set_enums_options
84
+ define_singleton_method( "t_#{set_name}_#{enum_name.to_s.pluralize}_options" ) do
85
+ send( "t_#{set_name}_#{enum_name.to_s.pluralize}" ).invert.to_a.map do | key_val |
86
+ key_val[0] = key_val[0].call if key_val[0].respond_to?(:call) && key_val[0].try(:arity) < 1
87
+ key_val
88
+ end
89
+ end
90
+
91
+ # set_enums_i
135
92
  define_singleton_method( "#{set_name}_#{enum_name.to_s.pluralize}_i" ) do
136
93
  self.send( "#{enum_name.to_s.pluralize}" ).slice( *self.send("#{set_name}_#{enum_name.to_s.pluralize}") ).values
137
94
  end
@@ -219,4 +176,119 @@ module EnumExt
219
176
  end
220
177
  end
221
178
 
179
+ # Ex using localize_enum with Request
180
+ # class Request
181
+ #
182
+ # if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
183
+ #
184
+ # humanize_enum :status, {
185
+ # #locale dependent example with pluralization and lambda:
186
+ # payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
187
+ #
188
+ # #locale dependent example with pluralization and proc:
189
+ # payed: proc{ I18n.t("request.status.payed", count: self.sum ) }
190
+ #
191
+ # #locale independent:
192
+ # ready_for_shipment: "Ready to go!"
193
+ # }
194
+ # end
195
+ #
196
+ # Example with block:
197
+ #
198
+ # humanize_enum :status do
199
+ # I18n.t("scope.#{status}")
200
+ # end
201
+
202
+ # Console:
203
+ # request.sum = 3
204
+ # request.payed!
205
+ # request.status # >> payed
206
+ # request.t_status # >> "Payed 3 dollars"
207
+ # Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
208
+
209
+ # if you need some substitution you can go like this
210
+ # localize_enum :status, {
211
+ # ..
212
+ # delivered: "Delivered at: %{date}"
213
+ # }
214
+ # request.delivered!
215
+ # request.t_status % {date: Time.now.to_s} # >> Delivered at: 05.02.2016
216
+ #
217
+ # Using in select:
218
+ # f.select :status, Request.t_statuses_options
219
+ #
220
+ # Rem: select options breaks when using lambda
221
+
222
+ def humanize_enum( *args, &block )
223
+ enum_name = args.shift
224
+ localizations = args.pop
225
+ enum_pural = enum_name.to_s.pluralize
226
+
227
+ self.instance_eval do
228
+
229
+ #t_enums
230
+ define_singleton_method( "t_#{enum_pural}" ) do
231
+ # if localization is abscent than block must be given
232
+ localizations.try(:with_indifferent_access) || localizations ||
233
+ send(enum_pural).keys.map {|en| [en, self.new( {enum_name => en} ).send("t_#{enum_name}")] }.to_h
234
+ end
235
+
236
+ #t_enums_options
237
+ define_singleton_method( "t_#{enum_pural}_options" ) do
238
+ send("t_#{enum_pural}").invert.to_a.map do | key_val |
239
+ # since all procs in t_enum are evaluated in context of a record than it's not always possible to create select options
240
+ key_val[0] = ( key_val[0].try(:call) || "Cannot create option for #{key_val[0]}" ) if key_val[0].respond_to?(:call) && key_val[0].try(:arity) < 1
241
+ key_val
242
+ end
243
+ end
244
+
245
+ #t_enum
246
+ define_method "t_#{enum_name}" do
247
+ t = block || localizations.try(:with_indifferent_access)[send(enum_name)]
248
+ if t.try(:lambda?)
249
+ t.try(:arity) == 1 && t.call( self ) || t.try(:call)
250
+ elsif t.is_a?(Proc)
251
+ instance_eval(&t)
252
+ else
253
+ t
254
+ end.to_s
255
+ end
256
+ end
257
+ end
258
+ alias localize_enum humanize_enum
259
+
260
+ # Simple way to translate enum.
261
+ # It use either given scope as second argument, or generated activerecord.attributes.model_name_underscore.enum_name
262
+ # If block is given than no scopes are taken in consider
263
+ def translate_enum( *args, &block )
264
+ enum_name = args.shift
265
+ t_scope = args.pop || "activerecord.attributes.#{self.name.underscore}.#{enum_name}"
266
+
267
+ translated_enums << enum_name.to_sym
268
+
269
+ if block_given?
270
+ humanize_enum( enum_name, &block )
271
+ else
272
+ humanize_enum( enum_name, send(enum_name.to_s.pluralize).keys.map{|en| [ en, Proc.new{ I18n.t("#{t_scope}.#{en}") }] }.to_h )
273
+ end
274
+
275
+ end
276
+
277
+ # It useful for Active Admin, since it use by default human_attribute_name
278
+ # to translate or humanize elements, if no translation given.
279
+ # So when enums translated it breaks default human_attribute_name since it's search I18n scope from
280
+ def human_attribute_name( name, options = {} )
281
+ enum_translated?(name) ? super( "t_#{name}", options ) : super( name, options )
282
+ end
283
+
284
+ # helper to determine is attribute is translated enum
285
+ def enum_translated?( name )
286
+ translated_enums.include?( name.to_sym )
287
+ end
288
+
289
+ private
290
+ def translated_enums
291
+ @translated_enums ||= Set.new
292
+ end
293
+
222
294
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enum_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - alekseyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-10 00:00:00.000000000 Z
11
+ date: 2017-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord