enum_ext 0.8.0 → 0.8.1

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
  SHA256:
3
- metadata.gz: 8d99346b1ae5f9458733025608cad6e8a1ab427091ce44d10a544e880722633c
4
- data.tar.gz: 6a1943ddedaa37022bdfe421dbc4c5d063c63149a96aaa0f05cdab35f423de6b
3
+ metadata.gz: 2c17ae56d510836b3106e8b1ca84b83f69a6854a0988192e71d7a7a62910dde0
4
+ data.tar.gz: 870773a5d09b15840695a8ff0ee57823b4bcc4c89753a88840b3daca7a69ae28
5
5
  SHA512:
6
- metadata.gz: ce540db8aca9002c6a46a5ae5eb7a45f7a296d4fd183493a8796e3b9dd007ebb04bc0793b1162b82e177de5b59ff06e8e553248a2aa4c725b17d3570d682444f
7
- data.tar.gz: 7db85461bd47c03b3169259f699a29e7a1855fd791d53fb4fe84995b812739fe4968b8184665dfd04230b71e2d78152dc8868f78f89452f37d6b20ed00c77ecc
6
+ metadata.gz: dd80dfc1f862eb03fbd9065af6f1eee36a95254ce4dd7e708073683ca4d5483163457cb5a8b96da851943d93246436a0897965d11b0f5478d966a4a590c82276
7
+ data.tar.gz: f07fd0d4869deba68067d29a0e6ac6a8003ae4df28dea658decd66455f12a5cbcdd622e816042f93de452c7186bb7af885b9b0d549b2fe3c40edfccd6b3fadf1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 0.8.1
2
+ * Fixes issue https://github.com/alekseyl/enum_ext/issues/50
3
+ * Better describe for supersets.
4
+ * Multiple readme and comments fixes
5
+
1
6
  # 0.8.0
2
7
  * Methods annotations added:
3
8
  * Full descriptions: Class.enum.describe(short=true) / Class.enum.describe_short / Class.enum.describe_long / Class.enum.describe_basic
data/README.md CHANGED
@@ -7,7 +7,7 @@ EnumExt extends rails enum with localization/translation and it's helpers, mass-
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'enum_ext', '~> 0.7'
10
+ gem 'enum_ext', '~> 0.8'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -26,12 +26,12 @@ Or install it yourself as:
26
26
 
27
27
  class SomeModel
28
28
  extend EnumExt
29
-
30
- enum kinds: {}, ext: [:enum_i, :enum_mass_assign, ]
31
- humanize_enum #...
32
- translate_enum #...
33
- ext_enum_sets #...
34
- end
29
+
30
+ enum status: {}, ext: [:enum_i, :enum_mass_assign, enum_supersets: { superset: [:basic_enum] } ]
31
+ humanize_enum #...
32
+ translate_enum #...
33
+ ext_enum_sets # if needed
34
+ end
35
35
  ```
36
36
 
37
37
  Let's assume that we have model Request representing some buying requests with enum **status**, and we have model Order with requests,
@@ -56,16 +56,16 @@ This is a preferable way now, and old helpers are private starting version 0.6!:
56
56
 
57
57
  ```ruby
58
58
  #Instead of three method calls:
59
- enum kind: {}
60
- enum_i :kind # will raise an private method error starting ver 0.6
61
- enum_mass_assign :kind # will raise an private method error starting ver 0.6
59
+ enum status: {}
60
+ enum_i :status # will raise an private method error starting ver 0.6
61
+ enum_mass_assign :status # will raise an private method error starting ver 0.6!!!
62
62
 
63
63
  #You should go with ext option instead:
64
- enum kinds: {}, ext: [:enum_i, :enum_mass_assign]
64
+ enum status: {}, ext: [:enum_i, :enum_mass_assign]
65
65
 
66
66
  # OR in case of standalone enum definition:
67
- enum kinds: {} # somewhere where you can't or don't want reach
68
- enum_ext :kinds, [:enum_i, :enum_mass_assign, enum_supersets: {} ]
67
+ enum status: {} # somewhere where you can't or don't want to reach
68
+ enum_ext :status, [:enum_i, :enum_mass_assign, enum_supersets: {} ]
69
69
  ```
70
70
  Rem: enum_ext could be called multiple times and merge later definitions, though I can't imagine why would you split it to multiple calls.
71
71
 
@@ -75,10 +75,10 @@ Rem: The only exceptions for the new syntax are full translation/humanization he
75
75
 
76
76
  ```ruby
77
77
  # GOOD:
78
- enum_ext :kinds, [:enum_i, :enum_mass_assign, :translate_enum, enum_supersets: {}]
78
+ enum_ext :status, [:enum_i, :enum_mass_assign, :translate_enum, enum_supersets: {}]
79
79
 
80
80
  # BAD (even if correctly defines internationalization):
81
- enum_ext :kinds, [:enum_i, :enum_mass_assign, :translate_enum, enum_supersets: {}] do
81
+ enum_ext :status, [:enum_i, :enum_mass_assign, :translate_enum, enum_supersets: {}] do
82
82
  I18n.t("scope.#{kind}")
83
83
  end
84
84
  ```
@@ -87,7 +87,7 @@ Rem: The only exceptions for the new syntax are full translation/humanization he
87
87
 
88
88
  ### Humanization (humanize_enum)
89
89
 
90
- if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
90
+ If app doesn't need internationalization, it may use humanize_enum to make enum output user friendly
91
91
 
92
92
  ```ruby
93
93
  humanize_enum :status, {
@@ -103,14 +103,13 @@ Rem: The only exceptions for the new syntax are full translation/humanization he
103
103
  ```
104
104
 
105
105
  This humanize_enum adds to instance:
106
- - t_in_cart, t_paid, t_ready_for_shipment
106
+ - t_status
107
107
 
108
- and to class:
109
- - t_statuses - as given or generated values
110
- - t_statuses_options - translated enum values options for select input
111
- - t_statuses_options_i - same as above but use int values with translations works for ActiveAdmin filters for instance
108
+ and to enum object:
109
+ - statuses.t_options - translated enum values options for select input
110
+ - statuses.t_options_i - same as above but use int values with translations works for ActiveAdmin filters for instance
111
+
112
112
 
113
-
114
113
  Example with block:
115
114
 
116
115
  ```ruby
@@ -122,12 +121,12 @@ Rem: The only exceptions for the new syntax are full translation/humanization he
122
121
  Example for select:
123
122
 
124
123
  ```ruby
125
- f.select :status, Request.t_statuses_options
124
+ f.select :status, Request.statuses.t_options
126
125
  ```
127
126
 
128
127
  in Active Admin filters
129
128
  ```ruby
130
- filter :status, as: :select, label: 'Status', collection: Request.t_statuses_options_i
129
+ filter :status, as: :select, label: 'Status', collection: Request.statuses.t_options_i
131
130
  ```
132
131
 
133
132
  **Rem:** select options may break when using lambda() or proc with instance method, but will survive with block
@@ -138,7 +137,7 @@ Rem: The only exceptions for the new syntax are full translation/humanization he
138
137
  request.paid!
139
138
  request.status # >> paid
140
139
  request.t_status # >> "paid 3 dollars"
141
- Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
140
+ Request.statuses.localizations # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
142
141
  ```
143
142
 
144
143
  Could be called multiple times, all humanization definitions will be merged under the hood.
@@ -158,6 +157,8 @@ Or it can be done with block either with translate or humanize:
158
157
  end
159
158
  ```
160
159
 
160
+ All humanization examples also should work same way as expected.
161
+
161
162
  ## Enum extended functionality
162
163
 
163
164
  ### Enum to_i shortcut ( enum_i )
@@ -172,6 +173,8 @@ Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name] or enum
172
173
  request.paid_i # 10
173
174
  ```
174
175
 
176
+ Rem: whenever underlying enum is not an integer will refuse to define helper and outputs WARNING
177
+
175
178
  ### Enum SuperSets (enum_supersets)
176
179
 
177
180
  **Use-case** whenever you need superset of enums to behave like a super enum.
@@ -185,16 +188,16 @@ Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name] or enum
185
188
  ```ruby
186
189
  enum status: [:in_cart, :waiting_for_payment, :paid, :packing, :ready_for_shipment, :on_delivery, :delivered],
187
190
  ext: [enum_supersets: {
188
- delivery_set: [:ready_for_shipment, :on_delivery], # for shipping department for example
191
+ around_delivery: [:ready_for_shipment, :on_delivery], # for shipping department for example
189
192
  in_warehouse: [:packing, :ready_for_shipment], # this scope is just for superposition example below
190
- sold: [:paid, :delivery_set, :in_warehouse, :delivered] # also you can define any superposition of already defined supersets or enum values
193
+ sold: [:paid, :around_delivery, :in_warehouse, :delivered] # also you can define any superposition of already defined supersets or enum values
191
194
  }]
192
195
 
193
196
  # supersets will be stored inside enum wrapper object, and can be de-referenced to basic enum values
194
197
  # using wrapper defined methods: "superset_enum_plural", i.e. statuses.sold_statuses -> [:paid, :packing, :ready_for_shipment, :on_delivery, :delivered]
195
198
  # so new supersets could be defined using Array operations against newly defined methods
196
199
  enum_ext :status, enum_supersets: {
197
- outside_warehouse: ( statuses.delivery_set_statuses - statuses.in_warehouse_statuses ) #... any other array operations like &, + and so can be used
200
+ outside_warehouse: ( statuses.around_delivery - statuses.in_warehouse ) #... any other array operations like &, + and so can be used
198
201
  }
199
202
  ```
200
203
 
@@ -202,39 +205,38 @@ it will generate:
202
205
 
203
206
  ```
204
207
  instance:
205
- - methods: delivery_set?, in_warehouse?
208
+ - methods: around_delivery?, in_warehouse?
206
209
 
207
210
  class:
208
- - named scopes: delivery_set, in_warehouse
209
- - parametrized scopes: with_statuses, without_statuses ( available as a standalone extension now, and will not be included by default in a versionafter 0.5.0)
211
+ - named scopes: around_delivery, in_warehouse
210
212
 
211
213
  enum methods:
212
214
  - Class.statuses.supersets -- will output superset definition hash
213
215
  - Class.statuses.supersets_raw -- will output superset decompositions to basic enum types hash
214
216
 
215
- - Class.statuses.delivery_superset (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
216
- - delivery_set_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
217
+ - Class.statuses.around_delivery (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
218
+ - around_delivery_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
217
219
 
218
- translation helpers ( started with t_... ):
219
- - Class.statuses.t_delivery_set_options (= [['translation or humanization', :ready_for_shipment] ...] ) for select inputs purposes
220
- - Class.statuses.t_delivery_set_options_i (= [['translation or humanization', 3] ...]) same as above but with integer as value ( for example to use in Active admin filters )
220
+ translation helpers grouped for superset ( started with t_... ):
221
+ - Class.statuses.t_around_delivery_options (= [['translation or humanization', :ready_for_shipment] ...] ) for select inputs purposes
222
+ - Class.statuses.t_around_delivery_options_i (= [['translation or humanization', 3] ...]) same as above but with integer as value ( for example to use in Active admin filters )
221
223
  ```
222
224
 
223
225
  ```ruby
224
226
  request.on_delivery!
225
- request.delivery_set? # >> true
227
+ request.around_delivery? # >> true
226
228
 
227
- Request.delivery_set.exists?(request) # >> true
229
+ Request.around_delivery.exists?(request) # >> true
228
230
  Request.in_warehouse.exists?(request) # >> false
229
231
 
230
- Request.delivery_set_statuses # >> ["ready_for_shipment", "on_delivery", "delivered"]
232
+ Request.statuses.around_delivery # >> ["ready_for_shipment", "on_delivery", "delivered"]
231
233
  ```
232
234
  Rem:
233
235
  supersets creation could be called multiple times defining a superposition of already defined sets ( considering previous example ):
234
236
 
235
237
  ```ruby
236
238
  enum_ext :status, enum_supersets: {
237
- outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )#... any other array operations like &, + and so can be used
239
+ outside_wharehouse: ( statuses.around_delivery_superset - statuses.in_warehouse_superset )#... any other array operations like &, + and so can be used
238
240
  }
239
241
  ```
240
242
 
@@ -242,8 +244,8 @@ Rem: you can refer previously defined set as usual kind in the same method call:
242
244
 
243
245
  ```ruby
244
246
  enum_ext :status, enum_supersets: {
245
- delivery_set: [:ready_for_shipment, :on_delivery, :delivered],
246
- not_in_cart: [:paid, :delivery_set] #
247
+ around_delivery: [:ready_for_shipment, :on_delivery, :delivered],
248
+ not_in_cart: [:paid, :around_delivery] #
247
249
  }
248
250
  ```
249
251
 
@@ -254,7 +256,7 @@ Rem: you can refer previously defined set as usual kind in the same method call:
254
256
  ext: [:multi_enum_scopes]
255
257
 
256
258
  # some place else:
257
- Request.with_statuses( :payed, :delivery_set ) # >> status IN (:payed, :ready_for_shipment, :on_delivery, :delivered)
259
+ Request.with_statuses( :payed, :around_delivery ) # >> status IN (:payed, :ready_for_shipment, :on_delivery, :delivered)
258
260
  Request.without_statuses( :payed, :in_warehouse ) # >> status NOT IN (:payed, :ready_for_shipment)
259
261
  ```
260
262
 
@@ -264,7 +266,7 @@ Rem: you can refer previously defined set as usual kind in the same method call:
264
266
 
265
267
  **Use-case:** it's often case when I need bulk update without callbacks, so it's gets frustrating to repeat:
266
268
  ```
267
- some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
269
+ some_scope.update_all(status: :new_status, update_at: Time.now)
268
270
  ```
269
271
  If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks and you
270
272
  have hundreds and thousands of records to change at once you better call update_all
@@ -323,15 +325,19 @@ Starting version 0.6 added support for rails 7+ enum definitions, that's making
323
325
  Now testings are done via `docker-compose up`. Look closer to Dockerfiles and `docker-compose.yml`
324
326
  to get the idea how they working simultaneously without interference with each other.
325
327
 
328
+ Rem. I'm always freaking googling everytime I need to run single test so I'll just keep here:
329
+
330
+ ```ruby
331
+ rake test TEST=test/test_enum_ext.rb TESTOPTS="--name=/bb/"
332
+ ```
326
333
 
327
334
  ## Development
328
335
 
329
336
  ## TODO
330
337
  [] better support for suffix/prefix as enum does
331
- [] describe method to observe current extension
338
+ [] add global config and allow global extension
332
339
 
333
340
  ## Contributing
334
-
335
341
  Bug reports and pull requests are welcome on GitHub at https://github.com/alekseyl/enum_ext or by email: leshchuk@gmail.com
336
342
 
337
343
 
@@ -2,15 +2,15 @@
2
2
  # but have no idea how to do this in a super-neat way, so it a little bit chaotic and experimental
3
3
  module EnumExt::Annotated
4
4
 
5
- # call it to see what's your enum current opitons
5
+ # call it to see what's your enum current options are
6
6
  def describe_basic
7
7
  puts yellow( "Basic #{enum_name} definition: \n" )
8
8
  print_hash(enum_values)
9
9
  end
10
10
 
11
- # call it to see all enum extensions defined.
11
+ # call it to see which enum extensions are defined.
12
12
  def describe_long
13
- puts yellow( "\nEnumExt extensions:" )
13
+ puts yellow( "\n\nEnumExt extensions:" )
14
14
 
15
15
  puts [
16
16
  describe_enum_i(false),
@@ -80,10 +80,19 @@ module EnumExt::Annotated
80
80
  description = if enabled_features[:supersets].blank?
81
81
  red( "\nSupersets not used!\n" )
82
82
  else
83
+ superset_method = enabled_features[:supersets].keys.first
83
84
  red( "\nSupersets definitions:\n" ) << inspect_hash(enabled_features[:supersets]) << <<~SUPERSETS
85
+
84
86
  # Instance methods added: #{enabled_features[:supersets].keys.join("?, ")}?
85
-
86
- # Class level methods added: #{enabled_features[:supersets].keys.join(", ")}
87
+ # Usage:
88
+ #{black("instance")}.#{cyan(superset_method)}?
89
+ # Will be equal true if any of: #{supersets_raw[superset_method].join("?, ")}? is true
90
+
91
+ # Class level methods/scopes added: #{enabled_features[:supersets].keys.join(", ")}
92
+ # Usage:
93
+ #{black(base_class.to_s)}.#{cyan(superset_method)}
94
+ # Will be getting all instances with #{enum_name} equals to any of: #{supersets_raw[superset_method].join(", ")}
95
+
87
96
  SUPERSETS
88
97
  end
89
98
 
@@ -1,18 +1,26 @@
1
1
  module EnumExt::BasicHelpers
2
2
 
3
+ private
3
4
  # Defines instance method a shortcut for getting integer value of an enum.
4
5
  # for enum named 'status' will generate:
5
6
  #
6
7
  # instance.status_i
7
- private
8
+ #
9
+ # Rem. Will not define helper when enum values are strings, and will print warning
8
10
  def enum_i( enum_name )
11
+ return puts(<<~NOTINTEGER) if columns_hash[enum_name.to_s].type != :integer
12
+ ---------------------NOTINTEGER WARNING!---------------------------
13
+ #{enum_name} is not an integer column, so enum_i helper useless and method will not be defined
14
+ NOTINTEGER
15
+
9
16
  define_method "#{enum_name}_i" do
10
- self.class.send("#{enum_name.to_s.pluralize}")[send(enum_name)].to_i
17
+ self.class.send(enum_name.to_s.pluralize)[send(enum_name)].to_i
11
18
  end
12
19
  end
13
20
 
14
21
  # Defines two scopes for one for an inclusion: `WHERE enum IN( enum1, enum2 )`,
15
22
  # and the second for an exclusion: `WHERE enum NOT IN( enum1, enum2 )`
23
+ # works fine with supersets and basic enums
16
24
  #
17
25
  # Ex:
18
26
  # Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
@@ -20,7 +28,6 @@ module EnumExt::BasicHelpers
20
28
  # Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
21
29
  def multi_enum_scopes(enum_name)
22
30
  enum_plural = enum_name.to_s.pluralize
23
- enum_obj = send(enum_plural)
24
31
 
25
32
  self.instance_eval do
26
33
  # EnumExt.define_superset_to_enum_method(self, enum_plural)
@@ -28,12 +35,12 @@ module EnumExt::BasicHelpers
28
35
 
29
36
  # with_enums scope
30
37
  scope "with_#{enum_plural}", -> (*enum_list) {
31
- enum_list.blank? ? nil : where( enum_name => enum_obj.superset_to_enum(*enum_list) )
38
+ enum_list.blank? ? nil : where( enum_name => send(enum_plural).superset_to_enum(*enum_list) )
32
39
  } if !respond_to?("with_#{enum_plural}") && respond_to?(:scope)
33
40
 
34
41
  # without_enums scope
35
42
  scope "without_#{enum_plural}", -> (*enum_list) {
36
- enum_list.blank? ? nil : where.not( enum_name => enum_obj.superset_to_enum(*enum_list) )
43
+ enum_list.blank? ? nil : where.not( enum_name => send(enum_plural).superset_to_enum(*enum_list) )
37
44
  } if !respond_to?("without_#{enum_plural}") && respond_to?(:scope)
38
45
  end
39
46
  end
@@ -42,7 +49,7 @@ module EnumExt::BasicHelpers
42
49
  #
43
50
  # Used for mass assigning for collection without callbacks it creates bang methods for collections using update_all.
44
51
  # it's often case when you need bulk update without callbacks, so it's gets frustrating to repeat:
45
- # some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
52
+ # some_scope.update_all(status: :new_status, update_at: Time.now)
46
53
  #
47
54
  # If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks
48
55
  # and you have lots of records to change at once you need update_all
@@ -34,7 +34,7 @@ module EnumExt::HumanizeHelpers
34
34
  # f.select :status, Request.t_statuses_options
35
35
  #
36
36
  # in select in Active Admin filter
37
- # collection: Request.t_statuses_options_i
37
+ # collection: Request.statuses.t_options_i
38
38
  #
39
39
  # Rem: select options breaks when using lambda() with params
40
40
  #
@@ -48,12 +48,11 @@ module EnumExt::HumanizeHelpers
48
48
  enum_name = args.shift
49
49
  localization_definitions = args.pop
50
50
  enum_plural = enum_name.to_s.pluralize
51
- enum_object = send( enum_plural )
52
51
 
53
52
  self.instance_eval do
54
53
  # instance.t_enum
55
54
  define_method "t_#{enum_name}" do
56
- t = block || enum_object.localizations[send(enum_name)]
55
+ t = block || self.class.send(enum_plural).localizations[send(enum_name)]
57
56
  if t.try(:lambda?)
58
57
  t.try(:arity) == 1 && t.call( self ) || t.try(:call)
59
58
  elsif t.is_a?(Proc)
@@ -64,7 +63,7 @@ module EnumExt::HumanizeHelpers
64
63
  end
65
64
 
66
65
  # if localization is absent than block must be given
67
- enum_object.localizations.merge!(
66
+ send(enum_plural).localizations.merge!(
68
67
  localization_definitions.try(:with_indifferent_access) ||
69
68
  send(enum_plural).map do |k, _v|
70
69
  # little bit hackerish: instantiate object just with enum setup and then call its t_.. method which
@@ -110,9 +109,8 @@ module EnumExt::HumanizeHelpers
110
109
  #
111
110
  def self.define_superset_humanization_helpers(base_class, superset_name, enum_name)
112
111
  enum_plural = enum_name.to_s.pluralize
113
- enum_object = base_class.send(enum_plural)
114
112
 
115
- enum_object.define_singleton_method( "t_#{superset_name}_options" ) do
113
+ base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}_options" ) do
116
114
  result = evaluate_localizations(send("t_#{superset_name}"))
117
115
  return result unless result.blank?
118
116
 
@@ -120,7 +118,7 @@ module EnumExt::HumanizeHelpers
120
118
  end
121
119
 
122
120
  # enums.t_options_i
123
- enum_object.define_singleton_method( "t_#{superset_name}_options_i" ) do
121
+ base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}_options_i" ) do
124
122
  result = evaluate_localizations_to_i( send("t_#{superset_name}") )
125
123
  return result unless result.to_h.values.all?(&:blank?)
126
124
 
@@ -129,10 +127,10 @@ module EnumExt::HumanizeHelpers
129
127
 
130
128
 
131
129
  # enums.t_superset ( translations or humanizations subset for a given set )
132
- enum_object.define_singleton_method( "t_#{superset_name}" ) do
130
+ base_class.send(enum_plural).define_singleton_method( "t_#{superset_name}" ) do
133
131
  return [(["Enum translations are missing. Did you forget to translate #{enum_name}"]*2)].to_h if localizations.blank?
134
132
 
135
- enum_object.localizations.slice( *enum_object.send(superset_name) )
133
+ base_class.send(enum_plural).localizations.slice( *base_class.send(enum_plural).send(superset_name) )
136
134
  end
137
135
  end
138
136
  end
@@ -1,69 +1,75 @@
1
1
  module EnumExt::SupersetHelpers
2
2
  # enum_supersets
3
- # This method intend for creating and using some sets of enum values,
4
- # you should
3
+ # **Use-case** whenever you need superset of enums to behave like a super enum.
5
4
  #
6
- # it creates: scopes for subsets,
7
- # instance method with ?
5
+ # You can do this with method **enum_supersets** it creates:
6
+ # - scopes for subsets,
7
+ # - instance methods with `?`
8
8
  #
9
- # For this call:
10
- # enum status: [:in_cart, :waiting_for_payment, :paid, :packing, :ready_for_shipment, :on_delivery, :delivered],
11
- # ext:[ , supersets: {
12
- # delivery_set: [:ready_for_shipment, :on_delivery] # for shipping department for example
13
- # in_warehouse: [:packing, :ready_for_shipment] # this scope is just for superposition example below
14
- # sold: [:payd, :delivery_set, :in_warehouse, :delivered]
15
- # } ]
16
- #Rem:
17
- # enum_supersets can be called twice defining a superposition of already defined supersets
18
- # based on array operations, with already defined array methods ( considering previous example ):
19
- # enum_supersets :status, {
20
- # outside_warehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
21
- # }
9
+ # For example:
10
+ # enum status: [:in_cart, :waiting_for_payment, :paid, :packing, :ready_for_shipment, :on_delivery, :delivered],
11
+ # ext: [enum_supersets: {
12
+ # around_delivery: [:ready_for_shipment, :on_delivery], # for shipping department for example
13
+ # in_warehouse: [:packing, :ready_for_shipment], # this scope is just for superposition example below
14
+ # sold: [:paid, :around_delivery, :in_warehouse, :delivered] # also you can define any superposition of already defined supersets or enum values
15
+ # }]
22
16
  #
23
- # so the enum_supersets will generate:
24
- # instance:
25
- # methods: delivery_set?, in_warehouse?
26
- # class:
27
- # named scopes: delivery_set, in_warehouse
28
- # class helpers:
29
- # - delivery_set_statuses (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
30
- # - delivery_set_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
31
- # class translation helpers ( started with t_... )
32
- # for select inputs purposes:
33
- # - t_delivery_set_statuses_options (= [['translation or humanization', :ready_for_shipment] ...])
34
- # same as above but with integer as value ( for example to use in Active admin filters )
35
- # - t_delivery_set_statuses_options_i (= [['translation or humanization', 3] ...])
36
-
37
- # Console:
38
- # request.on_delivery!
39
- # request.delivery_set? # >> true
40
-
41
- # Request.delivery_set.exists?(request) # >> true
42
- # Request.in_warehouse.exists?(request) # >> false
17
+ # # supersets will be stored inside enum wrapper object, and can be de-referenced to basic enum values
18
+ # # using wrapper defined methods: "superset_enum_plural", i.e. statuses.sold_statuses -> [:paid, :packing, :ready_for_shipment, :on_delivery, :delivered]
19
+ # # so new supersets could be defined using Array operations against newly defined methods
20
+ # enum_ext :status, enum_supersets: {
21
+ # outside_warehouse: ( statuses.around_delivery - statuses.in_warehouse ) #... any other array operations like &, + and so can be used
22
+ # }
23
+ #
24
+ # it will generate:
25
+ #
26
+ # instance:
27
+ # - methods: around_delivery?, in_warehouse?
28
+ #
29
+ # class:
30
+ # - named scopes: around_delivery, in_warehouse
31
+ #
32
+ # enum methods:
33
+ # - Class.statuses.supersets -- will output superset definition hash
34
+ # - Class.statuses.supersets_raw -- will output superset decompositions to basic enum types hash
43
35
  #
44
- # Request.statuses.supersets[:delivery_set] # >> [:ready_for_shipment, :on_delivery, :delivered]
36
+ # - Class.statuses.around_delivery (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
37
+ # - around_delivery_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
38
+ #
39
+ # translation helpers grouped for superset ( started with t_... ):
40
+ # - Class.statuses.t_around_delivery_options (= [['translation or humanization', :ready_for_shipment] ...] ) for select inputs purposes
41
+ # - Class.statuses.t_around_delivery_options_i (= [['translation or humanization', 3] ...]) same as above but with integer as value ( for example to use in Active admin filters )
42
+ #
43
+ # In console:
44
+ # request.on_delivery!
45
+ # request.around_delivery? # >> true
46
+ #
47
+ # Request.around_delivery.exists?(request) # >> true
48
+ # Request.in_warehouse.exists?(request) # >> false
49
+ #
50
+ # Request.statuses.around_delivery # >> ["ready_for_shipment", "on_delivery", "delivered"]
51
+
45
52
  private
46
53
  def enum_supersets( enum_name, options = {} )
47
54
  enum_plural = enum_name.to_s.pluralize
48
55
 
49
56
  self.instance_eval do
50
- enum_obj = send(enum_plural)
51
- enum_obj.supersets.merge!( options.transform_values{ _1.try(:map, &:to_s) || _1.to_s } )
57
+ send(enum_plural).supersets.merge!( options.transform_values{ _1.try(:map, &:to_s) || _1.to_s } )
52
58
 
53
59
  options.each do |superset_name, enum_vals|
54
- raise "Can't define superset with name: #{superset_name}, #{enum_plural} already has such method!" if enum_obj.respond_to?(superset_name)
60
+ raise "Can't define superset with name: #{superset_name}, #{enum_plural} already has such method!" if send(enum_plural).respond_to?(superset_name)
55
61
 
56
- enum_obj.supersets_raw[superset_name] = enum_obj.superset_to_enum(*enum_vals)
62
+ send(enum_plural).supersets_raw[superset_name] = send(enum_plural).superset_to_enum(*enum_vals)
57
63
 
58
- # class.statuses.superset_statuses
59
- enum_obj.define_singleton_method(superset_name) { enum_obj.superset_to_enum(*enum_vals) }
64
+ # class.enum_wrapper.superset
65
+ send(enum_plural).define_singleton_method(superset_name) { base_class.send(enum_plural).superset_to_enum(*enum_vals) }
60
66
 
61
67
  # superset_name scope
62
- scope superset_name, -> { where( enum_name => enum_obj.send(superset_name) ) } if respond_to?(:scope)
68
+ scope superset_name, -> { where( enum_name => send(enum_plural).send(superset_name) ) } if respond_to?(:scope)
63
69
 
64
70
  # instance.superset_name?
65
71
  define_method "#{superset_name}?" do
66
- send(enum_name) && enum_obj.send(superset_name).include?( send(enum_name) )
72
+ send(enum_name) && self.class.send(enum_plural).send(superset_name).include?( send(enum_name) )
67
73
  end
68
74
 
69
75
  EnumExt::HumanizeHelpers.define_superset_humanization_helpers( self, superset_name, enum_name )
@@ -1,3 +1,3 @@
1
1
  module EnumExt
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  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.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - alekseyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-02 00:00:00.000000000 Z
11
+ date: 2023-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord