enum_ext 0.5.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,172 @@
1
+ # I wanted to add some quick live annotation to what's defined and how it could be used
2
+ # but have no idea how to do this in a super-neat way, so it a little bit chaotic and experimental
3
+ module EnumExt::Annotated
4
+
5
+ # call it to see what's your enum current opitons
6
+ def describe_basic
7
+ puts yellow( "Basic #{enum_name} definition: \n" )
8
+ print_hash(enum_values)
9
+ end
10
+
11
+ # call it to see all enum extensions defined.
12
+ def describe_long
13
+ puts yellow( "\nEnumExt extensions:" )
14
+
15
+ puts [
16
+ describe_enum_i(false),
17
+ describe_mass_assign_enum(false),
18
+ describe_multi_enum_scopes(false),
19
+ describe_supersets(false),
20
+ describe_translations(false),
21
+ describe_humanizations(false)
22
+ ].join( "\n" + "-" * 100 + "\n" )
23
+ end
24
+
25
+ def describe(short = true)
26
+ describe_basic
27
+ short ? describe_short : describe_long
28
+ end
29
+
30
+ def describe_short
31
+ enabled, disabled = enabled_features.except(:key_sample).partition{!_2.blank?}.map{ |prt| prt.map(&:shift) }
32
+ puts <<~SHORT
33
+ #{yellow("EnumExt extensions:")}
34
+ #{cyan("Enabled")}: #{enabled.join(", ")}
35
+ #{red("Disabled")}: #{disabled.join(", ")}
36
+ SHORT
37
+
38
+ print_short(:supersets)
39
+ print_short(:translations)
40
+ print_short(:humanization)
41
+ end
42
+
43
+ # --------------------------------------------------------------------
44
+ # ------------- per helpers describers -------------------------------
45
+ # --------------------------------------------------------------------
46
+ def describe_enum_i(output = true)
47
+ description = basic_helpers_usage_header(:enum_i)
48
+ description << <<~ENUM_I if enabled_features[:enum_i]
49
+ #{black("instance")}.#{cyan( enabled_features[:enum_i] )}
50
+ # output will be same as #{base_class.to_s}.#{enum_name}[:#{enabled_features[:key_sample]}]
51
+ ENUM_I
52
+
53
+ output ? puts(description) : description
54
+ end
55
+
56
+ def describe_mass_assign_enum(output = true)
57
+ description = basic_helpers_usage_header(:mass_assign_enum)
58
+ description << <<~MASS_ASSIGN if enabled_features[:mass_assign_enum]
59
+ # To assign #{enabled_features[:key_sample]} to all elements of any_scope or relation call:
60
+ #{black(base_class.to_s)}.any_scope.#{cyan( enabled_features[:mass_assign_enum] )}
61
+ MASS_ASSIGN
62
+
63
+ output ? puts(description) : description
64
+ end
65
+
66
+ def describe_multi_enum_scopes(output = true)
67
+ description = basic_helpers_usage_header(:multi_enum_scopes)
68
+ description << <<~MULTI_SCOPES if enabled_features[:multi_enum_scopes]
69
+ # Two scopes: with_#{enum_name} and without_#{enum_name} are defined
70
+ # To get elements with a given enums or supersets values call:
71
+ #{black(base_class.to_s)}.#{cyan("with_#{enum_name}")}(:#{keys.sample(2).join(", :")})
72
+ \n# To get all elements except for the ones with enums or supersets values call:
73
+ #{black(base_class.to_s)}.#{cyan("without_#{enum_name}")}(:#{keys.sample(2).join(", :")})
74
+ MULTI_SCOPES
75
+
76
+ output ? puts(description) : description
77
+ end
78
+
79
+ def describe_supersets(output = true)
80
+ description = if enabled_features[:supersets].blank?
81
+ red( "\nSupersets not used!\n" )
82
+ else
83
+ red( "\nSupersets definitions:\n" ) << inspect_hash(enabled_features[:supersets]) << <<~SUPERSETS
84
+ # Instance methods added: #{enabled_features[:supersets].keys.join("?, ")}?
85
+
86
+ # Class level methods added: #{enabled_features[:supersets].keys.join(", ")}
87
+ SUPERSETS
88
+ end
89
+
90
+ output ? puts(description) : description
91
+ end
92
+
93
+ def describe_translations(output = true)
94
+ description = if enabled_features[:translations].blank?
95
+ red( "\nTranslations not used!\n" )
96
+ else
97
+ red( "\nTranslations definitions (will skip instance dependent translation)\n" ) <<
98
+ inspect_hash(enabled_features[:translations])
99
+ end
100
+
101
+ output ? puts(description) : description
102
+ end
103
+
104
+ def describe_humanizations(output = true)
105
+ description = if enabled_features[:humanization].blank?
106
+ red( "\nHumanization not used!\n" )
107
+ else
108
+ red( "\nHumanization definitions (will skip instance dependent humanization)\n" ) <<
109
+ inspect_hash(enabled_features[:humanization])
110
+ end
111
+
112
+ output ? puts(description) : description
113
+ end
114
+
115
+ private
116
+
117
+ def enabled_features
118
+ enum_sample = keys.first
119
+ {
120
+ key_sample: enum_sample,
121
+ enum_i: base_class.instance_methods.include?("#{enum_name}_i".to_sym) && "#{enum_name}_i",
122
+ mass_assign_enum: base_class.respond_to?("#{enum_sample}!") && "#{enum_sample}!",
123
+ multi_enum_scopes: base_class.respond_to?("with_#{enum_name.to_s.pluralize}") && "with_#{enum_name.to_s.pluralize}",
124
+ supersets: supersets_raw,
125
+ translations: try(:t_options),
126
+ humanization: try(:t_options)
127
+ }
128
+ end
129
+
130
+ def basic_helpers_usage_header(helper_name)
131
+ enabled_features[helper_name] ? "\n#{red(helper_name)} helpers enabled, usage:\n"
132
+ : "\n#{helper_name} wasn't used\n"
133
+ end
134
+
135
+ def print_hash(hsh)
136
+ defined?(ai) ? ap(hsh) : pp(hsh)
137
+ end
138
+
139
+ def inspect_hash(hsh)
140
+ defined?(ai) ? hsh.ai : hsh.inspect
141
+ end
142
+
143
+ def print_short(feature)
144
+ if enabled_features[feature].present?
145
+ puts black("#{feature.to_s.humanize}:")
146
+ print_hash(enabled_features[feature])
147
+ end
148
+ end
149
+
150
+ def yellow(str)
151
+ # yellow ANSI color
152
+ "\e[0;33;49m#{str}\e[0m"
153
+ end
154
+
155
+ def cyan(str)
156
+ # cyan ANSI color
157
+ "\e[0;36;49m#{str}\e[0m"
158
+ end
159
+
160
+ def red(str)
161
+ # red ANSI color
162
+ "\e[0;31;49m#{str}\e[0m"
163
+ end
164
+
165
+ def black(comment)
166
+ # bright black bold ANSI color
167
+ "\e[0;90;1;49m#{comment}\e[0m"
168
+ end
169
+
170
+ end
171
+
172
+
@@ -0,0 +1,79 @@
1
+ module EnumExt::BasicHelpers
2
+
3
+ # Defines instance method a shortcut for getting integer value of an enum.
4
+ # for enum named 'status' will generate:
5
+ #
6
+ # instance.status_i
7
+ private
8
+ def enum_i( enum_name )
9
+ define_method "#{enum_name}_i" do
10
+ self.class.send("#{enum_name.to_s.pluralize}")[send(enum_name)].to_i
11
+ end
12
+ end
13
+
14
+ # Defines two scopes for one for an inclusion: `WHERE enum IN( enum1, enum2 )`,
15
+ # and the second for an exclusion: `WHERE enum NOT IN( enum1, enum2 )`
16
+ #
17
+ # Ex:
18
+ # Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
19
+ # Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
20
+ # Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
21
+ def multi_enum_scopes(enum_name)
22
+ enum_plural = enum_name.to_s.pluralize
23
+ enum_obj = send(enum_plural)
24
+
25
+ self.instance_eval do
26
+ # EnumExt.define_superset_to_enum_method(self, enum_plural)
27
+ # EnumExt.define_summary_methods(self, enum_plural)
28
+
29
+ # with_enums scope
30
+ scope "with_#{enum_plural}", -> (*enum_list) {
31
+ enum_list.blank? ? nil : where( enum_name => enum_obj.superset_to_enum(*enum_list) )
32
+ } if !respond_to?("with_#{enum_plural}") && respond_to?(:scope)
33
+
34
+ # without_enums scope
35
+ scope "without_#{enum_plural}", -> (*enum_list) {
36
+ enum_list.blank? ? nil : where.not( enum_name => enum_obj.superset_to_enum(*enum_list) )
37
+ } if !respond_to?("without_#{enum_plural}") && respond_to?(:scope)
38
+ end
39
+ end
40
+
41
+ # Ex mass_assign_enum
42
+ #
43
+ # Used for mass assigning for collection without callbacks it creates bang methods for collections using update_all.
44
+ # 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)
46
+ #
47
+ # If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks
48
+ # and you have lots of records to change at once you need update_all
49
+ #
50
+ # mass_assign_enum( :status )
51
+ #
52
+ # class methods:
53
+ # in_cart! paid! in_warehouse! and so
54
+ #
55
+ # Console:
56
+ # request1.in_cart!
57
+ # request2.waiting_for_payment!
58
+ # Request.with_statuses( :in_cart, :waiting_for_payment ).payed!
59
+ # request1.paid? # >> true
60
+ # request2.paid? # >> true
61
+ # request1.updated_at # >> Time.now
62
+ #
63
+ # order.requests.paid.all?(&:paid?) # >> true
64
+ # order.requests.paid.delivered!
65
+ # order.requests.map(&:status).uniq #>> [:delivered]
66
+
67
+ def mass_assign_enum( *enums_names )
68
+ enums_names.each do |enum_name|
69
+ enum_vals = self.send( enum_name.to_s.pluralize )
70
+
71
+ enum_vals.keys.each do |enum_el|
72
+ define_singleton_method( "#{enum_el}!" ) do
73
+ self.update_all( {enum_name => enum_vals[enum_el]}.merge( self.column_names.include?('updated_at') ? {updated_at: Time.now} : {} ))
74
+ end
75
+ end
76
+ end
77
+ end
78
+ alias_method :enum_mass_assign, :mass_assign_enum
79
+ end
@@ -0,0 +1,78 @@
1
+ # This is an wrapper class for a basic enum.
2
+ # Since enum values will be freezed right after the definition, we can't enrich enum directly functionality
3
+ # We can only wrap it with our own object and delegate enum base base functionality internally
4
+ class EnumExt::EnumWrapper
5
+ include EnumExt::Annotated
6
+
7
+ # supersets is storing exact definitions, if you need a raw mapping use class.statuses.superset_statuses
8
+ attr_reader :enum_values, :supersets, :supersets_raw, :t_options_raw, :localizations, :base_class, :enum_name
9
+
10
+ delegate_missing_to :enum_values
11
+ delegate :inspect, to: :enum_values
12
+
13
+ def initialize(enum_values, base_class, enum_name)
14
+ @enum_values = enum_values
15
+ @supersets = ActiveSupport::HashWithIndifferentAccess.new
16
+ @supersets_raw = ActiveSupport::HashWithIndifferentAccess.new
17
+
18
+ @t_options_raw = ActiveSupport::HashWithIndifferentAccess.new
19
+ @localizations = ActiveSupport::HashWithIndifferentAccess.new
20
+
21
+ @base_class = base_class
22
+ @enum_name = enum_name
23
+ end
24
+
25
+ # ext_sets_to_kinds( :ready_for_shipment, :delivery_set ) -->
26
+ # [:ready_for_shipment, :on_delivery, :delivered]
27
+ def superset_to_enum( *enum_or_sets )
28
+ return [] if enum_or_sets.blank?
29
+ enum_or_sets_strs = enum_or_sets.map(&:to_s)
30
+
31
+ next_level_deeper = supersets.slice( *enum_or_sets_strs ).values.flatten
32
+ (enum_or_sets_strs & enum_values.keys | send(:superset_to_enum, *next_level_deeper)).uniq
33
+ end
34
+
35
+ def all
36
+ {
37
+ **enum_values,
38
+ supersets: {
39
+ **send(:supersets_raw)
40
+ }
41
+ }
42
+ end
43
+
44
+ def t_options_i
45
+ evaluate_localizations_to_i(localizations)
46
+ end
47
+
48
+ def t_options
49
+ evaluate_localizations(localizations)
50
+ end
51
+
52
+ alias_method :t, :localizations
53
+
54
+ private
55
+
56
+ def evaluate_localizations(t_enum_set)
57
+ # { kind => kind_translator, kind2 => kind2_translator } --> [[kind_translator, kind], [kind2_translator, kind2]]
58
+ t_enum_set.invert.to_a.map do | translator, enum_key |
59
+ # since all procs in t_enum are evaluated in context of a record than it's not always possible to create select options automatically
60
+ translation = if translator.respond_to?(:call)
61
+ if translator.arity < 1
62
+ translator.call rescue "Cannot create option for #{enum_key} ( proc fails to evaluate )"
63
+ else
64
+ "Cannot create option for #{enum_key} because of a lambda"
65
+ end
66
+ end || translator
67
+ [translation, enum_key]
68
+ end
69
+ end
70
+
71
+ def evaluate_localizations_to_i(t_enum_set)
72
+ # { kind => kind_translation, kind2 => kind2_translation } --> [[kind_translation, kind_i], [kind2_translation, kind2_i]]
73
+ evaluate_localizations(t_enum_set).map do | translation, name |
74
+ [ translation, self[name] ]
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,161 @@
1
+ module EnumExt::HumanizeHelpers
2
+
3
+ # if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
4
+ #
5
+ # class Request
6
+ # humanize_enum :status, {
7
+ # #locale dependent example with pluralization and lambda:
8
+ # payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
9
+ #
10
+ # #locale dependent example with pluralization and proc:
11
+ # payed: Proc.new{ I18n.t("request.status.payed", count: self.sum ) }
12
+ #
13
+ # #locale independent:
14
+ # ready_for_shipment: "Ready to go!"
15
+ # }
16
+ # end
17
+ #
18
+ # Could be called multiple times, all humanization definitions will be merged under the hood:
19
+ # humanize_enum :status, {
20
+ # payed: I18n.t("scope.#{status}")
21
+ # }
22
+ # humanize_enum :status, {
23
+ # billed: I18n.t("scope.#{status}")
24
+ # }
25
+ #
26
+ #
27
+ # Example with block:
28
+ #
29
+ # humanize_enum :status do
30
+ # I18n.t("scope.#{status}")
31
+ # end
32
+ #
33
+ # in views select:
34
+ # f.select :status, Request.t_statuses_options
35
+ #
36
+ # in select in Active Admin filter
37
+ # collection: Request.t_statuses_options_i
38
+ #
39
+ # Rem: select options breaks when using lambda() with params
40
+ #
41
+ # Console:
42
+ # request.sum = 3
43
+ # request.payed!
44
+ # request.status # >> payed
45
+ # request.t_status # >> "Payed 3 dollars"
46
+ # Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
47
+ def humanize_enum( *args, &block )
48
+ enum_name = args.shift
49
+ localization_definitions = args.pop
50
+ enum_plural = enum_name.to_s.pluralize
51
+ enum_object = send( enum_plural )
52
+
53
+ self.instance_eval do
54
+ # instance.t_enum
55
+ define_method "t_#{enum_name}" do
56
+ t = block || enum_object.localizations[send(enum_name)]
57
+ if t.try(:lambda?)
58
+ t.try(:arity) == 1 && t.call( self ) || t.try(:call)
59
+ elsif t.is_a?(Proc)
60
+ instance_eval(&t)
61
+ else
62
+ t
63
+ end.to_s
64
+ end
65
+
66
+ # if localization is absent than block must be given
67
+ enum_object.localizations.merge!(
68
+ localization_definitions.try(:with_indifferent_access) ||
69
+ send(enum_plural).map do |k, _v|
70
+ # little bit hackerish: instantiate object just with enum setup and then call its t_.. method which
71
+ [k, Proc.new{ self.new({ enum_name => k }).send("t_#{enum_name}") }]
72
+ end.to_h.with_indifferent_access
73
+ )
74
+
75
+ # hm.. lost myself here, why did I implement this method
76
+ define_method "t_#{enum_name}=" do |new_val|
77
+ send("#{enum_name}=", new_val)
78
+ end
79
+
80
+ end
81
+ end
82
+ alias localize_enum humanize_enum
83
+
84
+ # Simple way to translate enum.
85
+ # It use either given scope as second argument, or generated activerecord.attributes.model_name_underscore.enum_name
86
+ # If block is given than no scopes are taken in consider
87
+ def translate_enum( *args, &block )
88
+ enum_name = args.shift
89
+ enum_plural = enum_name.to_s.pluralize
90
+ t_scope = args.pop || "activerecord.attributes.#{self.name.underscore}.#{enum_plural}"
91
+
92
+ if block_given?
93
+ humanize_enum( enum_name, &block )
94
+ else
95
+ humanize_enum( enum_name, send(enum_plural).keys.map{|en| [ en, Proc.new{ I18n.t("#{t_scope}.#{en}") }] }.to_h )
96
+ end
97
+ end
98
+
99
+ # human_attribute_name is redefined for automation like this:
100
+ # p #{object.class.human_attribute_name( attr_name )}:
101
+ # p object.send(attr_name)
102
+ def human_attribute_name( name, options = {} )
103
+ # if name starts from t_ and there is a column with the last part then ...
104
+ name[0..1] == 't_' && column_names.include?(name[2..-1]) ? super( name[2..-1], options ) : super( name, options )
105
+ end
106
+
107
+
108
+ # t_... methods for supersets will just slice
109
+ # original enum t_.. methods output and return only superset related values from it
110
+ #
111
+ def self.define_superset_humanization_helpers(base_class, superset_name, enum_name)
112
+ enum_plural = enum_name.to_s.pluralize
113
+ enum_object = base_class.send(enum_plural)
114
+
115
+ enum_object.define_singleton_method( "t_#{superset_name}_options" ) do
116
+ result = evaluate_localizations(send("t_#{superset_name}"))
117
+ return result unless result.blank?
118
+
119
+ [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2]
120
+ end
121
+
122
+ # enums.t_options_i
123
+ enum_object.define_singleton_method( "t_#{superset_name}_options_i" ) do
124
+ result = evaluate_localizations_to_i( send("t_#{superset_name}") )
125
+ return result unless result.to_h.values.all?(&:blank?)
126
+
127
+ [["Enum translations are missing. Did you forget to translate #{enum_name}"]*2]
128
+ end
129
+
130
+
131
+ # enums.t_superset ( translations or humanizations subset for a given set )
132
+ enum_object.define_singleton_method( "t_#{superset_name}" ) do
133
+ return [(["Enum translations are missing. Did you forget to translate #{enum_name}"]*2)].to_h if localizations.blank?
134
+
135
+ enum_object.localizations.slice( *enum_object.send(superset_name) )
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ # # t_... - are translation dependent methods
142
+ # # This one is a narrow case helpers just a quick subset of t_ enums options for a set
143
+ # # class.t_enums_options
144
+ # enum_obj.define_singleton_method( "t_#{superset_name}_options" ) do
145
+ # return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] unless respond_to?( "t_#{enum_plural}_options_raw" )
146
+ #
147
+ # send("t_#{enum_plural}_options_raw", send("t_#{superset_name}_#{enum_plural}") )
148
+ # end
149
+ #
150
+ # # class.t_enums_options_i
151
+ # enum_obj.define_singleton_method( "t_#{superset_name}_options_i" ) do
152
+ # return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] unless respond_to?( "t_#{enum_plural}_options_raw_i" )
153
+ #
154
+ # send("t_#{enum_plural}_options_raw_i", send("t_#{superset_name}_#{enum_plural}") )
155
+ # end
156
+ #
157
+ # enum_obj.define_singleton_method( "t_#{superset_name}_options" ) do
158
+ # return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] if t_options_raw.blank?
159
+ #
160
+ # t_options_raw["t_#{superset_name}"]
161
+ # end
@@ -0,0 +1,77 @@
1
+ module EnumExt::SupersetHelpers
2
+ # enum_supersets
3
+ # This method intend for creating and using some sets of enum values,
4
+ # you should
5
+ #
6
+ # it creates: scopes for subsets,
7
+ # instance method with ?
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
+ # }
22
+ #
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
43
+ #
44
+ # Request.statuses.supersets[:delivery_set] # >> [:ready_for_shipment, :on_delivery, :delivered]
45
+ private
46
+ def enum_supersets( enum_name, options = {} )
47
+ enum_plural = enum_name.to_s.pluralize
48
+
49
+ 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 } )
52
+
53
+ 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)
55
+
56
+ enum_obj.supersets_raw[superset_name] = enum_obj.superset_to_enum(*enum_vals)
57
+
58
+ # class.statuses.superset_statuses
59
+ enum_obj.define_singleton_method(superset_name) { enum_obj.superset_to_enum(*enum_vals) }
60
+
61
+ # superset_name scope
62
+ scope superset_name, -> { where( enum_name => enum_obj.send(superset_name) ) } if respond_to?(:scope)
63
+
64
+ # instance.superset_name?
65
+ define_method "#{superset_name}?" do
66
+ send(enum_name) && enum_obj.send(superset_name).include?( send(enum_name) )
67
+ end
68
+
69
+ EnumExt::HumanizeHelpers.define_superset_humanization_helpers( self, superset_name, enum_name )
70
+ end
71
+
72
+ end
73
+ end
74
+ alias_method :ext_enum_sets, :enum_supersets
75
+ end
76
+
77
+
@@ -1,3 +1,3 @@
1
1
  module EnumExt
2
- VERSION = "0.5.2"
2
+ VERSION = "0.8.0"
3
3
  end