enumerize 0.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +11 -12
  5. data/CHANGELOG.md +112 -0
  6. data/Gemfile +5 -22
  7. data/Gemfile.global +19 -0
  8. data/Gemfile.mongo_mapper +6 -0
  9. data/Gemfile.rails42 +6 -0
  10. data/README.md +185 -9
  11. data/Rakefile +2 -4
  12. data/enumerize.gemspec +1 -0
  13. data/lib/enumerize/activerecord.rb +17 -28
  14. data/lib/enumerize/attribute.rb +41 -9
  15. data/lib/enumerize/base.rb +28 -17
  16. data/lib/enumerize/hooks/formtastic.rb +3 -8
  17. data/lib/enumerize/hooks/sequel_dataset.rb +15 -0
  18. data/lib/enumerize/hooks/simple_form.rb +5 -11
  19. data/lib/enumerize/hooks/uniqueness.rb +3 -8
  20. data/lib/enumerize/integrations/rspec/matcher.rb +107 -26
  21. data/lib/enumerize/mongoid.rb +13 -0
  22. data/lib/enumerize/predicatable.rb +7 -16
  23. data/lib/enumerize/predicates.rb +3 -1
  24. data/lib/enumerize/scope/activerecord.rb +37 -0
  25. data/lib/enumerize/scope/mongoid.rb +35 -0
  26. data/lib/enumerize/scope/sequel.rb +40 -0
  27. data/lib/enumerize/sequel.rb +57 -0
  28. data/lib/enumerize/set.rb +18 -8
  29. data/lib/enumerize/value.rb +10 -9
  30. data/lib/enumerize/version.rb +1 -1
  31. data/lib/enumerize.rb +23 -1
  32. data/spec/enumerize/integrations/rspec/matcher_spec.rb +258 -0
  33. data/spec/spec_helper.rb +28 -0
  34. data/test/activerecord_test.rb +143 -7
  35. data/test/attribute_test.rb +22 -0
  36. data/test/base_test.rb +2 -2
  37. data/test/formtastic_test.rb +3 -12
  38. data/test/mongo_mapper_test.rb +6 -0
  39. data/test/mongoid_test.rb +62 -6
  40. data/test/multiple_test.rb +21 -0
  41. data/test/predicates_test.rb +6 -0
  42. data/test/sequel_test.rb +291 -0
  43. data/test/set_test.rb +14 -0
  44. data/test/simple_form_test.rb +0 -1
  45. data/test/support/view_test_helper.rb +4 -0
  46. data/test/test_helper.rb +23 -2
  47. data/test/value_test.rb +51 -21
  48. metadata +39 -9
  49. data/Gemfile.rails4 +0 -23
  50. data/lib/enumerize/form_helper.rb +0 -23
  51. data/test/rspec_matcher_test.rb +0 -76
  52. data/test/rspec_spec.rb +0 -13
@@ -4,12 +4,16 @@ module Enumerize
4
4
 
5
5
  def initialize(klass, name, options={})
6
6
  raise ArgumentError, ':in option is required' unless options[:in]
7
+ raise ArgumentError, ':scope option does not work with option :multiple' if options[:multiple] && options[:scope]
7
8
 
8
9
  extend Multiple if options[:multiple]
9
10
 
10
11
  @klass = klass
11
12
  @name = name.to_sym
12
- @values = Array(options[:in]).map { |v| Value.new(self, *v) }
13
+
14
+ value_class = options.fetch(:value_class, Value)
15
+ @values = Array(options[:in]).map { |v| value_class.new(self, *v) }
16
+
13
17
  @value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
14
18
  @value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
15
19
 
@@ -36,6 +40,10 @@ module Enumerize
36
40
  @value_hash[value.to_s] unless value.nil?
37
41
  end
38
42
 
43
+ def find_values(*values)
44
+ values.map { |value| find_value(value) }.compact
45
+ end
46
+
39
47
  def i18n_scopes
40
48
  @i18n_scopes ||= if i18n_scope
41
49
  scopes = Array(i18n_scope)
@@ -67,6 +75,10 @@ module Enumerize
67
75
  values.map { |v| [v.text, v.to_s] }
68
76
  end
69
77
 
78
+ def respond_to_missing?(method, include_private=false)
79
+ @value_hash.include?(method.to_s) || super
80
+ end
81
+
70
82
  def define_methods!(mod)
71
83
  mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
72
84
  def #{name}
@@ -84,8 +96,6 @@ module Enumerize
84
96
  end
85
97
 
86
98
  def #{name}=(new_value)
87
- _enumerized_values_for_validation[:#{name}] = new_value.nil? ? nil : new_value.to_s
88
-
89
99
  allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
90
100
  allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
91
101
 
@@ -96,6 +106,10 @@ module Enumerize
96
106
  else
97
107
  @#{name} = allowed_value_or_nil
98
108
  end
109
+
110
+ _enumerized_values_for_validation['#{name}'] = new_value.nil? ? nil : new_value.to_s
111
+
112
+ allowed_value_or_nil
99
113
  end
100
114
 
101
115
  def #{name}_text
@@ -107,9 +121,27 @@ module Enumerize
107
121
  end
108
122
  RUBY
109
123
  end
124
+
125
+ private
126
+
127
+ def method_missing(method)
128
+ if @value_hash.include?(method.to_s)
129
+ find_value(method)
130
+ else
131
+ super
132
+ end
133
+ end
110
134
  end
111
135
 
112
136
  module Multiple
137
+ def find_default_value(value)
138
+ if value.respond_to?(:call)
139
+ value
140
+ else
141
+ find_values(*value)
142
+ end
143
+ end
144
+
113
145
  def define_methods!(mod)
114
146
  mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
115
147
  def #{name}
@@ -131,19 +163,19 @@ module Enumerize
131
163
  end
132
164
 
133
165
  def #{name}=(values)
134
- _enumerized_values_for_validation[:#{name}] = values.respond_to?(:map) ? values.map(&:to_s) : values
135
-
136
166
  @_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
137
- string_values = #{name}.values.map(&:to_str)
167
+ raw_values = #{name}.values.map(&:value)
138
168
 
139
169
  if defined?(super)
140
- super string_values
170
+ super raw_values
141
171
  elsif respond_to?(:write_attribute, true)
142
- write_attribute '#{name}', string_values
172
+ write_attribute '#{name}', raw_values
143
173
  else
144
- @#{name} = string_values
174
+ @#{name} = raw_values
145
175
  end
146
176
 
177
+ _enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.reject(&:blank?).map(&:to_s) : values
178
+
147
179
  #{name}
148
180
  end
149
181
  RUBY
@@ -2,6 +2,7 @@ module Enumerize
2
2
  module Base
3
3
  def self.included(base)
4
4
  base.extend ClassMethods
5
+ base.singleton_class.prepend ClassMethods::Hook
5
6
 
6
7
  if base.respond_to?(:validate)
7
8
  base.validate :_validate_enumerized_attributes
@@ -28,9 +29,11 @@ module Enumerize
28
29
  @enumerized_attributes ||= AttributeMap.new
29
30
  end
30
31
 
31
- def inherited(subclass)
32
- enumerized_attributes.add_dependant subclass.enumerized_attributes
33
- super
32
+ module Hook
33
+ def inherited(subclass)
34
+ enumerized_attributes.add_dependant subclass.enumerized_attributes
35
+ super subclass
36
+ end
34
37
  end
35
38
 
36
39
  private
@@ -50,10 +53,14 @@ module Enumerize
50
53
  end
51
54
 
52
55
  def read_attribute_for_validation(key)
56
+ key = key.to_s
57
+
53
58
  if _enumerized_values_for_validation.has_key?(key)
54
59
  _enumerized_values_for_validation[key]
55
- else
60
+ elsif defined?(super)
56
61
  super
62
+ else
63
+ send(key)
57
64
  end
58
65
  end
59
66
 
@@ -78,22 +85,26 @@ module Enumerize
78
85
 
79
86
  def _set_default_value_for_enumerized_attributes
80
87
  self.class.enumerized_attributes.each do |attr|
81
- # remove after dropping support for Rails 3.x
82
- # https://github.com/brainspec/enumerize/issues/101
83
- attr_value = begin
84
- public_send(attr.name)
85
- rescue ActiveModel::MissingAttributeError
86
- nil
87
- end
88
+ next if attr.default_value.nil?
89
+ begin
90
+ if respond_to?(attr.name)
91
+ attr_value = public_send(attr.name)
92
+ else
93
+ next
94
+ end
88
95
 
89
- if !attr_value && !_enumerized_values_for_validation.key?(attr.name)
90
- value = attr.default_value
96
+ value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
91
97
 
92
- if value.respond_to?(:call)
93
- value = value.arity == 0 ? value.call : value.call(self)
94
- end
98
+ if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
99
+ value = attr.default_value
100
+
101
+ if value.respond_to?(:call)
102
+ value = value.arity == 0 ? value.call : value.call(self)
103
+ end
95
104
 
96
- public_send("#{attr.name}=", value)
105
+ public_send("#{attr.name}=", value)
106
+ end
107
+ rescue ActiveModel::MissingAttributeError
97
108
  end
98
109
  end
99
110
  end
@@ -3,13 +3,8 @@ require 'active_support/concern'
3
3
  module Enumerize
4
4
  module Hooks
5
5
  module FormtasticFormBuilderExtension
6
- extend ActiveSupport::Concern
7
6
 
8
- included do
9
- alias_method_chain :input, :enumerize
10
- end
11
-
12
- def input_with_enumerize(method, options={})
7
+ def input(method, options={})
13
8
  klass = object.class
14
9
 
15
10
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
@@ -20,10 +15,10 @@ module Enumerize
20
15
  end
21
16
  end
22
17
 
23
- input_without_enumerize(method, options)
18
+ super(method, options)
24
19
  end
25
20
  end
26
21
  end
27
22
  end
28
23
 
29
- ::Formtastic::FormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
24
+ ::Formtastic::FormBuilder.send :prepend, Enumerize::Hooks::FormtasticFormBuilderExtension
@@ -0,0 +1,15 @@
1
+ module Enumerize
2
+ module Hooks
3
+ module SequelDataset
4
+ def literal_append(sql, v)
5
+ if v.is_a?(Enumerize::Value)
6
+ super(sql, v.value)
7
+ else
8
+ super(sql, v)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ ::Sequel::Dataset.send :prepend, Enumerize::Hooks::SequelDataset
@@ -3,21 +3,15 @@ require 'active_support/concern'
3
3
  module Enumerize
4
4
  module Hooks
5
5
  module SimpleFormBuilderExtension
6
- extend ActiveSupport::Concern
7
6
 
8
- included do
9
- alias_method_chain :input, :enumerize
10
- alias_method_chain :input_field, :enumerize
11
- end
12
-
13
- def input_with_enumerize(attribute_name, options={}, &block)
7
+ def input(attribute_name, options={}, &block)
14
8
  add_input_options_for_enumerized_attribute(attribute_name, options)
15
- input_without_enumerize(attribute_name, options, &block)
9
+ super(attribute_name, options, &block)
16
10
  end
17
11
 
18
- def input_field_with_enumerize(attribute_name, options={})
12
+ def input_field(attribute_name, options={})
19
13
  add_input_options_for_enumerized_attribute(attribute_name, options)
20
- input_field_without_enumerize(attribute_name, options)
14
+ super(attribute_name, options)
21
15
  end
22
16
 
23
17
  private
@@ -37,4 +31,4 @@ module Enumerize
37
31
  end
38
32
  end
39
33
 
40
- ::SimpleForm::FormBuilder.send :include, Enumerize::Hooks::SimpleFormBuilderExtension
34
+ ::SimpleForm::FormBuilder.send :prepend, Enumerize::Hooks::SimpleFormBuilderExtension
@@ -3,21 +3,16 @@ require 'active_support/concern'
3
3
  module Enumerize
4
4
  module Hooks
5
5
  module UniquenessValidator
6
- extend ActiveSupport::Concern
7
6
 
8
- included do
9
- alias_method_chain :validate_each, :enumerize
10
- end
11
-
12
- def validate_each_with_enumerize(record, name, value)
7
+ def validate_each(record, name, value)
13
8
  if record.class.respond_to?(:enumerized_attributes) && (attr = record.class.enumerized_attributes[name])
14
9
  value = attr.find_value(value).try(:value)
15
10
  end
16
11
 
17
- validate_each_without_enumerize(record, name, value)
12
+ super(record, name, value)
18
13
  end
19
14
  end
20
15
  end
21
16
  end
22
17
 
23
- ::ActiveRecord::Validations::UniquenessValidator.send :include, Enumerize::Hooks::UniquenessValidator
18
+ ::ActiveRecord::Validations::UniquenessValidator.send :prepend, Enumerize::Hooks::UniquenessValidator
@@ -2,37 +2,57 @@ module Enumerize
2
2
  module Integrations
3
3
  module RSpec
4
4
  class Matcher
5
- attr_accessor :attr, :values, :subject, :default
6
5
 
7
- def initialize(attr)
8
- self.attr = attr
6
+ def initialize(expected_attr)
7
+ self.expected_attr = expected_attr
9
8
  end
10
9
 
11
- def in(*values)
12
- self.values = values.map(&:to_s).sort
10
+ def in(*expected_values)
11
+ self.expected_values = expected_values.flatten
13
12
  self
14
13
  end
15
14
 
16
- def with_default(default)
17
- self.default = default.to_s
15
+ def with_default(expected_default)
16
+ self.expected_default = expected_default.to_s
18
17
  self
19
18
  end
20
19
 
21
- def failure_message
22
- message = " expected :#{attr} to allow value#{values.size == 1 ? nil : 's'}: #{quote_values(values)},"
23
- message += " but it allows #{quote_values(enumerized_values)} instead"
20
+ def with_i18n_scope(expected_i18n_scope)
21
+ self.expected_i18n_scope = expected_i18n_scope
22
+ self
23
+ end
24
24
 
25
- if default && !matches_default_value?
26
- message = " expected :#{attr} to have #{default.inspect} as default value,"
27
- message += " but it sets #{enumerized_default.inspect} instead"
28
- end
25
+ def with_predicates(expected_predicates)
26
+ self.expected_predicates = expected_predicates
27
+ self
28
+ end
29
+
30
+ def with_multiple(expected_multiple)
31
+ self.expected_multiple = expected_multiple
32
+ self
33
+ end
34
+
35
+ def with_scope(expected_scope)
36
+ self.expected_scope = expected_scope
37
+ self
38
+ end
39
+
40
+ def failure_message
41
+ "Expected #{expectation}"
42
+ end
29
43
 
30
- message
44
+ def failure_message_when_negated
45
+ "Did not expect #{expectation}"
31
46
  end
32
47
 
33
48
  def description
34
- description = "enumerize :#{attr} in: #{quote_values(values)}"
35
- description += " with #{default.inspect} as default value" if default
49
+ description = "define enumerize :#{expected_attr}"
50
+ description += " in: #{quote_values(expected_values)}" if expected_values
51
+ description += " with #{expected_default.inspect} as default value" if expected_default
52
+ description += " i18n_scope: #{expected_i18n_scope.inspect}" if expected_i18n_scope
53
+ description += " predicates: #{expected_predicates.inspect}" if expected_predicates
54
+ description += " multiple: #{expected_multiple.inspect}" if expected_multiple
55
+ description += " scope: #{expected_scope.inspect}" if expected_scope
36
56
 
37
57
  description
38
58
  end
@@ -41,36 +61,97 @@ module Enumerize
41
61
  self.subject = subject
42
62
  matches = true
43
63
 
44
- matches &= matches_attributes?
45
- matches &= matches_default_value? if default
64
+ matches &= matches_attribute?
65
+ matches &= matches_values? if expected_values
66
+ matches &= matches_default_value? if expected_default
67
+ matches &= matches_i18n_scope? if expected_i18n_scope
68
+ matches &= matches_predicates? if expected_predicates
69
+ matches &= matches_multiple? if expected_multiple
70
+ matches &= matches_scope? if expected_scope
46
71
 
47
72
  matches
48
73
  end
49
74
 
50
75
  private
76
+ attr_accessor :expected_attr, :expected_values, :subject, :expected_default,
77
+ :expected_i18n_scope, :expected_predicates, :expected_multiple,
78
+ :expected_scope
51
79
 
52
- def matches_attributes?
53
- values == enumerized_values
80
+ def expectation
81
+ "#{subject.class.name} to #{description}"
82
+ end
83
+
84
+ def matches_attribute?
85
+ attributes.present?
86
+ end
87
+
88
+ def matches_values?
89
+ matches_array_values? || matches_hash_values?
90
+ end
91
+
92
+ def matches_array_values?
93
+ sorted_values == enumerized_values
94
+ end
95
+
96
+ def matches_hash_values?
97
+ return unless expected_values.first.is_a?(Hash)
98
+ expected_values.first.all? { |k, v| enumerized_value_hash[k.to_s] == v; }
54
99
  end
55
100
 
56
101
  def matches_default_value?
57
- default == enumerized_default
102
+ expected_default == enumerized_default
103
+ end
104
+
105
+ def matches_i18n_scope?
106
+ attributes.i18n_scope == expected_i18n_scope
107
+ end
108
+
109
+ def matches_predicates?
110
+ if expected_predicates.is_a?(TrueClass)
111
+ subject.respond_to?("#{sorted_values.first}?")
112
+ else
113
+ subject.respond_to?("#{expected_attr}_#{attributes.values.first}?")
114
+ end
115
+ end
116
+
117
+ def matches_multiple?
118
+ subject.public_send(expected_attr).is_a?(Enumerize::Set)
119
+ end
120
+
121
+ def matches_scope?
122
+ if expected_scope.is_a?(TrueClass)
123
+ subject_class.respond_to?("with_#{expected_attr}")
124
+ else
125
+ subject_class.respond_to?(expected_scope[:scope])
126
+ end
127
+ end
128
+
129
+ def sorted_values
130
+ @sorted_values ||=expected_values.map(&:to_s).sort
58
131
  end
59
132
 
60
133
  def enumerized_values
61
- @enumerized_values ||= attributes[attr.to_s].values.sort
134
+ @enumerized_values ||= attributes.values.sort
62
135
  end
63
136
 
64
137
  def enumerized_default
65
- @enumerized_default ||= attributes[attr.to_s].default_value
138
+ @enumerized_default ||= attributes.default_value
139
+ end
140
+
141
+ def enumerized_value_hash
142
+ @enumerized_value_hash ||= attributes.instance_variable_get('@value_hash')
66
143
  end
67
144
 
68
145
  def attributes
69
- subject.class.enumerized_attributes.attributes
146
+ subject_class.enumerized_attributes.attributes[expected_attr.to_s]
147
+ end
148
+
149
+ def subject_class
150
+ @subject_class ||= subject.class
70
151
  end
71
152
 
72
153
  def quote_values(values)
73
- values.map(&:inspect).join(', ')
154
+ sorted_values.map(&:inspect).join(', ')
74
155
  end
75
156
  end
76
157
  end
@@ -0,0 +1,13 @@
1
+ module Enumerize
2
+ module MongoidSupport
3
+ def enumerize(name, options={})
4
+ super
5
+
6
+ _enumerize_module.dependent_eval do
7
+ if self < ::Mongoid::Document
8
+ after_initialize :_set_default_value_for_enumerized_attributes
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,29 +1,20 @@
1
1
  module Enumerize
2
2
  module Predicatable
3
- def method_missing(method, *args, &block)
4
- if boolean_method?(method)
5
- define_query_methods
6
- send(method, *args, &block)
7
- else
8
- super
9
- end
10
- end
11
-
12
3
  def respond_to_missing?(method, include_private=false)
13
- boolean_method?(method)
4
+ predicate_method?(method) || super
14
5
  end
15
6
 
16
7
  private
17
8
 
18
- def define_query_methods
19
- @attr.values.each do |value|
20
- unless singleton_methods.include?(:"#{value}?")
21
- define_query_method(value)
22
- end
9
+ def method_missing(method, *args, &block)
10
+ if predicate_method?(method)
11
+ predicate_call(method[0..-2], *args, &block)
12
+ else
13
+ super
23
14
  end
24
15
  end
25
16
 
26
- def boolean_method?(method)
17
+ def predicate_method?(method)
27
18
  method[-1] == '?' && @attr.values.include?(method[0..-2])
28
19
  end
29
20
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
1
3
  module Enumerize
2
4
  # Predicate methods.
3
5
  #
@@ -61,7 +63,7 @@ module Enumerize
61
63
  end
62
64
 
63
65
  def names
64
- values.map { |v| "#{v}?" }
66
+ values.map { |v| "#{v.tr('-', '_')}?" }
65
67
  end
66
68
 
67
69
  def build(klass)
@@ -0,0 +1,37 @@
1
+ module Enumerize
2
+ module Scope
3
+ module ActiveRecord
4
+ def enumerize(name, options={})
5
+ super
6
+
7
+ _enumerize_module.dependent_eval do
8
+ if self < ::ActiveRecord::Base
9
+ if options[:scope]
10
+ _define_activerecord_scope_methods!(name, options)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def _define_activerecord_scope_methods!(name, options)
19
+ scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
20
+
21
+ define_singleton_method scope_name do |*values|
22
+ values = enumerized_attributes[name].find_values(*values).map(&:value)
23
+ values = values.first if values.size == 1
24
+
25
+ where(name => values)
26
+ end
27
+
28
+ if options[:scope] == true
29
+ define_singleton_method "without_#{name}" do |*values|
30
+ values = enumerized_attributes[name].find_values(*values).map(&:value)
31
+ where(arel_table[name].not_in(values))
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ module Enumerize
2
+ module Scope
3
+ module Mongoid
4
+ def enumerize(name, options={})
5
+ super
6
+
7
+ _enumerize_module.dependent_eval do
8
+ if self < ::Mongoid::Document
9
+ if options[:scope]
10
+ _define_mongoid_scope_methods!(name, options)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def _define_mongoid_scope_methods!(name, options)
19
+ scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
20
+
21
+ define_singleton_method scope_name do |*values|
22
+ values = enumerized_attributes[name].find_values(*values).map(&:value)
23
+ self.in(name => values)
24
+ end
25
+
26
+ if options[:scope] == true
27
+ define_singleton_method "without_#{name}" do |*values|
28
+ values = enumerized_attributes[name].find_values(*values).map(&:value)
29
+ not_in(name => values)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ module Enumerize
2
+ module Scope
3
+ module Sequel
4
+ def enumerize(name, options={})
5
+ super
6
+
7
+ _enumerize_module.dependent_eval do
8
+ if defined?(::Sequel::Model) && self < ::Sequel::Model
9
+ if options[:scope]
10
+ _define_sequel_scope_methods!(name, options)
11
+ end
12
+
13
+ require 'enumerize/hooks/sequel_dataset'
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def _define_sequel_scope_methods!(name, options)
21
+ klass = self
22
+ scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
23
+
24
+ def_dataset_method scope_name do |*values|
25
+ values = values.map { |value| klass.enumerized_attributes[name].find_value(value).value }
26
+ values = values.first if values.size == 1
27
+
28
+ where(name => values)
29
+ end
30
+
31
+ if options[:scope] == true
32
+ def_dataset_method "without_#{name}" do |*values|
33
+ values = values.map { |value| klass.enumerized_attributes[name].find_value(value).value }
34
+ exclude(name => values)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end