attribute-filters 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.yardopts +1 -0
  3. data/ChangeLog +501 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +7 -7
  6. data/Manifest.txt +7 -0
  7. data/README.md +59 -30
  8. data/Rakefile +1 -0
  9. data/attribute-filters.gemspec +4 -4
  10. data/docs/COMMON-FILTERS.md +1067 -0
  11. data/docs/HISTORY +42 -0
  12. data/docs/TODO +29 -12
  13. data/docs/USAGE.md +718 -818
  14. data/lib/attribute-filters.rb +4 -2
  15. data/lib/attribute-filters/attribute_set.rb +144 -73
  16. data/lib/attribute-filters/attribute_set_annotations.rb +110 -77
  17. data/lib/attribute-filters/attribute_set_attrquery.rb +51 -8
  18. data/lib/attribute-filters/attribute_set_enum.rb +44 -38
  19. data/lib/attribute-filters/attribute_set_query.rb +62 -12
  20. data/lib/attribute-filters/backports.rb +36 -4
  21. data/lib/attribute-filters/common_filters.rb +83 -37
  22. data/lib/attribute-filters/common_filters/bare.rb +29 -0
  23. data/lib/attribute-filters/common_filters/case.rb +34 -19
  24. data/lib/attribute-filters/common_filters/convert.rb +259 -0
  25. data/lib/attribute-filters/common_filters/join.rb +37 -30
  26. data/lib/attribute-filters/common_filters/order.rb +105 -0
  27. data/lib/attribute-filters/common_filters/pick.rb +90 -0
  28. data/lib/attribute-filters/common_filters/presence.rb +70 -0
  29. data/lib/attribute-filters/common_filters/split.rb +37 -21
  30. data/lib/attribute-filters/common_filters/squeeze.rb +28 -9
  31. data/lib/attribute-filters/common_filters/strip.rb +7 -3
  32. data/lib/attribute-filters/dsl_attr_virtual.rb +2 -1
  33. data/lib/attribute-filters/dsl_filters.rb +14 -61
  34. data/lib/attribute-filters/dsl_sets.rb +238 -88
  35. data/lib/attribute-filters/helpers.rb +7 -1
  36. data/lib/attribute-filters/meta_set.rb +38 -0
  37. data/lib/attribute-filters/version.rb +1 -1
  38. data/spec/attribute-filters_spec.rb +178 -16
  39. data/spec/spec_helper.rb +9 -4
  40. metadata +129 -69
  41. metadata.gz.sig +0 -0
@@ -20,11 +20,20 @@ module ActiveModel
20
20
  # @param set_object [AttributeSet] attribute set containing set names for which the query will be made
21
21
  # @param am_object [Object] model object which has access to attributes (may be an instance of ActiveRecord or similar)
22
22
  # @param attribute_name [Sting,Symbol] name of attribute the query is made for
23
- def initialize(set_object, am_object, attribute_name)
24
- @set_object = set_object
23
+ def initialize(attribute_name = nil, am_object = nil)
24
+ if am_object.nil?
25
+ am_object = attribute_name
26
+ attribute_name = nil
27
+ unless am_object.included_modules.include?(::ActiveModel::AttributeFilters)
28
+ raise ::ArgumentError, "incompatible object passed to AttributeSet::AttrQuery (not a model class?)"
29
+ end
30
+ end
25
31
  @am_object = am_object
26
- @attribute_name = attribute_name.to_s
27
32
  @next_method = nil
33
+ unless attribute_name.nil?
34
+ @set_object = @am_object.class.filter_attribute(attribute_name)
35
+ @attribute_name = attribute_name.to_s
36
+ end
28
37
  end
29
38
 
30
39
  # This is a proxy method that causes some calls to be
@@ -50,7 +59,15 @@ module ActiveModel
50
59
  # @param args [Array] optional arguments to be passed to a method call
51
60
  # @yield optional block to be passed to a method call
52
61
  def method_missing(method_sym, *args, &block)
53
- case method_sym.to_sym
62
+ method_sym = method_sym.to_sym
63
+
64
+ if @attribute_name.nil?
65
+ @attribute_name = method_sym.to_s
66
+ @set_object = @am_object.class.filter_attribute(@attribute_name)
67
+ return self
68
+ end
69
+
70
+ case method_sym
54
71
  when :are, :is, :one, :is_one, :in, :list, :be, :should,
55
72
  :the, :a, :sets, :in_sets, :set, :in_a_set, :in_set, :belongs_to
56
73
  self
@@ -63,16 +80,40 @@ module ActiveModel
63
80
  @set_object.include?(*args, &block)
64
81
 
65
82
  when :accessible?, :is_accessible?
66
- @am_object.all_accessible_attributes.include?(@attribute_name)
83
+ @am_object.class.accessible_attributes.include?(@attribute_name)
67
84
 
68
85
  when :inaccessible?, :is_inaccessible?
69
86
  @am_object.all_inaccessible_attributes.include?(@attribute_name)
70
87
 
71
88
  when :protected?, :is_protected?
72
- @am_object.all_protected_attributes.include?(@attribute_name)
89
+ @am_object.class.protected_attributes.include?(@attribute_name)
90
+
91
+ when :virtual?, :is_virtual?
92
+ @am_object.class.attribute_filters_virtual.include?(@attribute_name)
93
+
94
+ when :semi_real?, :is_semi_real?
95
+ @am_object.class.treat_as_real.include?(@attribute_name)
96
+
97
+ when :valid?, :is_valid?
98
+ return false unless @am_object.send(:__all_attributes).include?(@attribute_name)
99
+ return true if @am_object.valid?
100
+ not @am_object.errors.has_key?(@attribute_name.to_sym)
101
+
102
+ when :invalid?, :is_invalid?
103
+ return true unless @am_object.send(:__all_attributes).include?(@attribute_name)
104
+ return false if @am_object.valid?
105
+ @am_object.errors.has_key?(@attribute_name.to_sym)
106
+
107
+ when :changed?, :is_changed?, :has_changed?
108
+ return false unless @am_object.changed? && @am_object.send(:__all_attributes).include?(@attribute_name)
109
+ @am_object.changes.key?(@attribute_name)
110
+
111
+ when :unchanged?, :is_unchanged?, :hasnt_changed?, :not_changed?
112
+ return true unless @am_object.changed?
113
+ @am_object.changes.key?(@attribute_name)
73
114
 
74
115
  else
75
- set_name_str = method_sym.to_s.dup
116
+ set_name_str = method_sym.to_s
76
117
  if !@set_object.respond_to?(method_sym) && set_name_str.slice!(/\?\z/) == '?'
77
118
  @set_object.include?(set_name_str.to_sym, &block)
78
119
  else
@@ -96,7 +137,9 @@ module ActiveModel
96
137
  :set, :in_a_set, :in_set, :in?, :in_set?, :in_a_set?, :in_the_set?, :the_set?, :set?,
97
138
  :is_one_that?, :one_that?, :that?, :belongs_to?, :belongs_to,
98
139
  :protected?, :is_protected?, :inaccessible?, :is_inaccessible?,
99
- :accessible?, :is_accessible?
140
+ :accessible?, :is_accessible?, :valid?, :is_valid?, :invalid?, :is_invalid?,
141
+ :virtual?, :is_virtual?, :semi_real?, :is_semi_real?,
142
+ :changed?, :has_changed?, :is_changed?, :unchanged?, :hasnt_changed?, :is_unchanged?, :not_changed?
100
143
  true
101
144
  else
102
145
  @set_object.respond_to?(name) || name.to_s.slice(-1,1) == '?'
@@ -6,70 +6,76 @@
6
6
  #
7
7
  # This file contains AttributeSet::Enumerable module and AttributeSet::Enumerator class.
8
8
 
9
- require 'set'
10
-
11
9
  # This module adds some enumerable properties to AttributeSet objects.
12
10
  module ActiveModel
13
- class AttributeSet < ::Set
11
+ class AttributeSet < Hash
12
+
14
13
  module Enumerable
15
14
  # @private
16
- def select
17
- if block_given?
18
- ActiveModel::AttributeSet.new.tap do |r|
19
- each { |e| r << e if yield(e) }
20
- r.send(:copy_annotations, self) unless r.empty?
21
- end
15
+ def select(&block)
16
+ block_given? or return AttributeSet::Enumerator.new(self, :select)
17
+ ActiveModel::AttributeSet.new.tap { |r| each_pair { |k, v| r[k] = v if yield(k, v) } }
18
+ end
19
+
20
+ # Selects attributes that have setters and getters.
21
+ # @param binding [Object] optional object which should have setters and getters (default: the calling context)
22
+ # @return [AttributeSet::Enumerator, AttributeSet] resulting set or an enumerator if block is not given
23
+ def select_accessible(binding = nil)
24
+ if binding.nil?
25
+ select { |a| respond_to?(a) && respond_to?("#{a}=") }
22
26
  else
23
- AttributeSet::Enumerator.new(self, :select)
27
+ select { |a| binding.respond_to?(a) && binding.respond_to?("#{a}=") }
24
28
  end
25
29
  end
26
30
 
27
31
  # @private
28
32
  def reject
29
- if block_given?
30
- ActiveModel::AttributeSet.new.tap do |r|
31
- each { |e| r << e unless yield(e) }
32
- r.send(:copy_annotations, self) unless r.empty?
33
- end
34
- else
35
- AttributeSet::Enumerator.new(self, :reject)
36
- end
33
+ block_given? or return AttributeSet::Enumerator.new(self, :reject)
34
+ ActiveModel::AttributeSet.new.tap { |r| each_pair { |k, v| r[k] = v unless yield(k, v) } }
37
35
  end
38
36
 
39
37
  # @private
40
38
  def collect
41
- if block_given?
42
- ActiveModel::AttributeSet.new.tap do |r|
43
- each { |e| r << yield(e) }
44
- end
45
- else
46
- AttributeSet::Enumerator.new(self, :map)
47
- end
39
+ block_given? ? super { |k, v| yield(k) } : AttributeSet::Enumerator.new(self, :map)
48
40
  end
49
41
  alias_method :map, :collect
50
42
 
51
43
  # @private
52
- def sort
53
- r = ActiveModel::AttributeSet.new(super)
54
- r.send(:copy_annotations, self) unless r.empty?
55
- r
44
+ def each
45
+ block_given? ? each_pair { |k, v| yield(k, v) } : AttributeSet::Enumerator.new(self, :each)
56
46
  end
57
47
 
58
48
  # @private
59
- def sort_by
60
- r = ActiveModel::AttributeSet.new(super)
61
- r.send(:copy_annotations, self) unless r.empty?
62
- r
49
+ def each_pair
50
+ block_given? ? super : AttributeSet::Enumerator.new(self, :each_pair)
63
51
  end
64
52
 
65
- # @private
66
- def each
67
- if block_given?
68
- super
53
+ # Iterates through the name and value of each attribute found in a set.
54
+ # If the attribute has no getter method in the context of the given object, it is not evaluated.
55
+ #
56
+ # @param am_object [Object] active model object
57
+ # @param no_presence_check [Boolean] optional flag that if +true+ causes enumerator
58
+ # not to check if a getter method exists (defaults to +false+ – checks are done)
59
+ # @return [void,AttributeSet::Enumerator]
60
+ def each_name_value(am_object, no_presence_check = false)
61
+ block_given? or return AttributeSet::Enumerator.new(self, :each_name_value, am_object, no_presence_check)
62
+ if no_presence_check
63
+ each { |name| yield(name, am_object.public_send(name)) }
69
64
  else
70
- AttributeSet::Enumerator.new(self, :each)
65
+ each { |name| yield(name, am_object.public_send(name)) if am_object.respond_to?(name) }
71
66
  end
72
67
  end
68
+
69
+ # @private
70
+ def sort
71
+ ActiveModel::AttributeSet[super]
72
+ end
73
+
74
+ # @private
75
+ def sort_by
76
+ block_given? ? ActiveModel::AttributeSet[super] : AttributeSet::Enumerator.new(self, :sort_by)
77
+ end
78
+
73
79
  end # module Enumerable
74
80
 
75
81
  # This class adds enumerator for AttributeSet elements.
@@ -30,14 +30,19 @@ module ActiveModel
30
30
  def initialize(set_object, am_object = nil)
31
31
  if am_object.nil?
32
32
  am_object = set_object
33
+ unless am_object.included_modules.include?(::ActiveModel::AttributeFilters)
34
+ raise ::ArgumentError, "incompatible object passed to AttributeSet::Query (not a model class?)"
35
+ end
33
36
  set_object = ::ActiveModel::AttributeSet.new
34
37
  end
35
- if set_object.is_a?(::Symbol) || set_object.is_a?(::String)
36
- set_object = am_object.class.attribute_set(set_object).dup
37
- elsif !set_object.is_a?(::ActiveModel::AttributeSet)
38
- set_object = ::ActiveModel::AttributeSet.new(set_object)
38
+
39
+ if set_object.is_a?(::Symbol) || set_object.is_a?(::String) # global set assigned to model class
40
+ set_object = am_object.attribute_set_simple(set_object) # - duplicated in class method that gets a set
41
+ elsif !set_object.nil? && !set_object.is_a?(::ActiveModel::AttributeSet) # any other object
42
+ set_object = ::ActiveModel::AttributeSet.new(set_object) # - duplicated in AttributeSet initializer
39
43
  end
40
- @set_object = set_object
44
+
45
+ @set_object = set_object # AttributeSet (assuming it's duplicated if needed)
41
46
  @am_object = am_object
42
47
  @next_method = nil
43
48
  end
@@ -69,42 +74,76 @@ module ActiveModel
69
74
  # @yield optional block to be passed to a method call or to a queued method call
70
75
  # @return [Object] the returned value is passed back from called method
71
76
  def method_missing(method_sym, *args, &block)
72
- case method_sym.to_sym
77
+ method_sym = method_sym.to_sym
78
+
79
+ # set name as a method name
80
+ if @set_object.nil?
81
+ @set_object = @am_object.class.attribute_set(method_sym)
82
+ return self
83
+ end
84
+
85
+ # neutral method
86
+ case method_sym
73
87
  when :are, :is, :be, :should
74
88
  return self
75
89
  end
76
- # Special selectors
90
+
91
+ # special selectors
77
92
  if @next_method.nil?
78
- case method_sym.to_sym
93
+ case method_sym
94
+
79
95
  when :all, :any, :none, :one
80
96
  ::ActiveModel::AttributeSet::Query.new(@set_object, @am_object). # new obj. == thread-safe
81
97
  next_step(method_sym.to_s << "?", args, block)
98
+
82
99
  when :list, :show
83
100
  ::ActiveModel::AttributeSet::Query.new(@set_object, @am_object).
84
101
  next_step(:select, args, block)
102
+
85
103
  when :valid?, :is_valid?, :are_valid?, :all_valid?, :are_all_valid?
86
104
  self.all.valid?
105
+
87
106
  when :invalid?, :is_not_valid?, :any_invalid?, :are_not_valid?, :not_valid?, :is_any_invalid?
88
107
  self.any.invalid?
108
+
109
+ when :changed?, :any_changed?, :have_changed?, :have_any_changed?, :is_any_changed?, :has_any_changed?, :has_changed?
110
+ self.any.changed?
111
+
112
+ when :unchanged?, :none_changed?, :nothing_changed?, :is_unchanged?, :are_all_unchanged?,
113
+ :all_unchanged?, :havent_changed?, :arent_changed?, :are_not_changed?, :none_changed?, :not_changed?
114
+ self.all.unchanged?
115
+
89
116
  else
90
117
  r = @set_object.public_method(method_sym).call(*args, &block)
91
118
  return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
92
119
  ::ActiveModel::AttributeSet::Query.new(r, @am_object)
93
120
  end
94
121
  else
95
- m, args, block = @next_method
122
+ n_m, n_args, n_block = @next_method
96
123
  @next_method = nil
97
124
  # m contains a method that we should call on a set of names (e.g. all? or any?)
98
125
  # method_sym contains a method to be called on each attribute from a set (e.g. present?)
99
126
  r = case method_sym
127
+
100
128
  when :valid?
101
129
  @am_object.valid?
102
- @set_object.public_method(m).call(*args) { |atr| not @am_object.errors.has_key?(atr.to_sym) }
130
+ method_for_each_attr(n_m, *args) { |atr| not @am_object.errors.include?(atr.to_sym) }
131
+
103
132
  when :invalid?
104
133
  @am_object.valid?
105
- @set_object.public_method(m).call(*args) { |atr| @am_object.errors.has_key?(atr.to_sym) }
134
+ method_for_each_attr(n_m, *args) { |atr| @am_object.errors.include?(atr.to_sym) }
135
+
136
+ when :changed?
137
+ method_for_each_attr(n_m, *args) { |atr| @am_object.changes.key?(atr) }
138
+
139
+ when :unchanged?
140
+ method_for_each_attr(n_m, *args) { |atr| not @am_object.changes.key?(atr) }
141
+
106
142
  else
107
- @set_object.public_method(m).call { |atr| @am_object.public_send(atr).public_method(method_sym).call(*args, &block) }
143
+ @set_object.public_method(n_m).call(*n_args) do |atr|
144
+ @am_object.public_send(atr).public_method(method_sym).call(*args, &block)
145
+ end
146
+
108
147
  end
109
148
  return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
110
149
  ::ActiveModel::AttributeSet::Query.new(r, @am_object)
@@ -120,6 +159,11 @@ module ActiveModel
120
159
  true
121
160
  when :valid?, :is_valid?, :are_valid?, :all_valid?, :are_all_valid?
122
161
  true
162
+ when :changed?, :any_changed?, :have_changed?, :have_any_changed?, :is_any_changed?, :has_any_changed?, :has_changed?
163
+ true
164
+ when :unchanged?, :none_changed?, :nothing_changed?, :is_unchanged?, :are_all_unchanged?,
165
+ :all_unchanged?, :havent_changed?, :arent_changed?, :are_not_changed?, :none_changed?, :not_changed?
166
+ true
123
167
  else
124
168
  @set_object.respond_to?(name)
125
169
  end
@@ -185,6 +229,12 @@ module ActiveModel
185
229
  @next_method = [method_name, args, block]
186
230
  return self
187
231
  end
232
+
233
+ private
234
+
235
+ def method_for_each_attr(m, *args, &block)
236
+ @set_object.public_method(m).call(*args, &block)
237
+ end
188
238
  end # class Query
189
239
  end # class AttributeSet
190
240
  end # module ActiveModel
@@ -11,7 +11,6 @@
11
11
  class Object
12
12
 
13
13
  unless method_defined?(:public_send)
14
-
15
14
  # @private
16
15
  def public_send(name, *args)
17
16
  unless public_methods.include?(name.to_s)
@@ -19,11 +18,9 @@ class Object
19
18
  end
20
19
  send(name, *args)
21
20
  end
22
-
23
21
  end
24
22
 
25
23
  unless method_defined?(:public_method)
26
-
27
24
  # @private
28
25
  def public_method(name)
29
26
  unless public_methods.include?(name.to_s)
@@ -31,7 +28,42 @@ class Object
31
28
  end
32
29
  method(name)
33
30
  end
34
-
35
31
  end
36
32
 
37
33
  end # class Object
34
+
35
+ # @private
36
+ # @abstract This class is here for compatibility reasons.
37
+ class Hash
38
+
39
+ # @private
40
+ unless method_defined?(:deep_merge)
41
+ def deep_merge(o)
42
+ dup.deep_merge!(o)
43
+ end
44
+ end
45
+
46
+ # @private
47
+ unless method_defined?(:deep_merge!)
48
+ def deep_merge!(other_hash)
49
+ other_hash.each_pair do |k, ov|
50
+ my_v = self[k]
51
+ self[k] = my_v.is_a?(Hash) && ov.is_a?(Hash) ? my_v.deep_merge(ov) : ov
52
+ end
53
+ self
54
+ end
55
+ end
56
+
57
+ # @private
58
+ unless method_defined?(:deep_dup)
59
+ def deep_dup
60
+ duplicate = self.dup
61
+ duplicate.each_pair do |k, ov|
62
+ my_v = duplicate[k]
63
+ duplicate[k] = my_v.is_a?(Hash) && ov.is_a?(Hash) ? my_v.deep_dup : ov
64
+ end
65
+ duplicate
66
+ end
67
+ end
68
+
69
+ end # class Hash
@@ -11,63 +11,109 @@
11
11
  module ActiveModel
12
12
  module AttributeFilters
13
13
 
14
- # This method is a callback method that tries to call all
15
- # known filtering methods if they are present.
16
- #
17
- # Calling order:
18
- # * split_attributes
19
- # * join_attributes
20
- # * squeeze_attributes
21
- # * strip_attributes
22
- # * upcase_attributes
23
- # * downcase_attributes
24
- # * capitalize_attributes
25
- # * fully_capitalize_attributes
26
- # * titleize_attributes
27
- def filter_attributes
28
- respond_to?(:split_attributes) and split_attributes
29
- respond_to?(:join_attributes) and join_attributes
30
- respond_to?(:squeeze_attributes) and squeeze_attributes
31
- respond_to?(:strip_attributes) and strip_attributes
32
- respond_to?(:upcase_attributes) and upcase_attributes
33
- respond_to?(:downcase_attributes) and downcase_attributes
34
- respond_to?(:capitalize_attributes) and capitalize_attributes
35
- respond_to?(:fully_capitalize_attributes) and fully_capitalize_attributes
36
- respond_to?(:titleize_attributes) and titleize_attributes
37
- end
14
+ # This module holds method for marking methods as filters.
15
+ module FilteringRegistration
16
+ # This method marks a method as filtering method
17
+ # and associates it with the given name of an attribute set it uses.
18
+ #
19
+ # @param method_name [Symbol] name of a method
20
+ # @param set_name [Symbol] name of an attribute set
21
+ # @return [void]
22
+ def filtering_method(method_name, set_name)
23
+ set_name = set_name.to_sym
24
+ return unless method_defined?(method_name)
25
+ f = (@__filtering_sets ||= MetaSet.new)
26
+ f[set_name] = method_name unless f.key?(set_name)
27
+ nil
28
+ end
29
+ alias_method :has_filtering_method, :filtering_method
30
+
31
+ end # module FilteringRegistration
38
32
 
39
33
  # This module contains common, ready-to-use filtering methods.
40
34
  module Common
41
-
42
35
  # @private
43
36
  module CommonFilter
37
+ include FilteringRegistration
38
+
44
39
  # @private
45
40
  def included(base)
46
- if base == ActiveModel::AttributeFilters::Common
47
- base::ClassMethods.send(:include, self::ClassMethods)
41
+
42
+ # merge filtering sets from filtering modules to models
43
+ fs = @__filtering_sets
44
+ base.class_eval { (@__filtering_sets ||= MetaSet.new).merge!(fs) } unless fs.nil?
45
+
46
+ if base.const_defined?(:ClassMethods) &&
47
+ base.instance_of?(::Module) &&
48
+ base.const_get(:ClassMethods).instance_of?(::Module)
49
+
50
+ # If we're here then this module was included by some other module
51
+ # (one of our own filtering submodules).
52
+ base.class_eval <<-EVAL
53
+ unless singleton_class.method_defined?(:included)
54
+ def self.included(base)
55
+ fs = @__filtering_sets
56
+ base.class_eval { (@__filtering_sets ||= MetaSet.new).merge!(fs) } unless fs.nil?
57
+ base.extend ClassMethods
58
+ end
59
+ end
60
+ module ClassMethods
61
+ include #{self.name}::ClassMethods
62
+ end
63
+ EVAL
64
+
48
65
  else
66
+
67
+ # If we're here then this module was included
68
+ # by some model or other class.
49
69
  base.extend ClassMethods
70
+
50
71
  end
51
72
  end
52
- end
53
-
54
- extend CommonFilter
73
+ end # module CommonFilter
55
74
 
56
75
  # This module contains class methods used by the DSL
57
- # to create keywords for common operations.
76
+ # to create keywords for common filtering operations.
77
+ # These keywords can be used in filtering submodules
78
+ # and in any model that includes them.
58
79
  module ClassMethods
59
80
  end
60
81
 
82
+ extend CommonFilter
83
+
61
84
  # Include all default filters
62
85
  # that should be available
63
86
  # when Common module is included.
64
-
65
- require 'attribute-filters/common_filters/strip'
66
- require 'attribute-filters/common_filters/case'
67
- require 'attribute-filters/common_filters/squeeze'
68
- require 'attribute-filters/common_filters/split'
69
- require 'attribute-filters/common_filters/join'
87
+ Dir[File.join(File.dirname(__FILE__), 'common_filters', '*.rb')].each do |f|
88
+ require f
89
+ end
70
90
 
71
91
  end # module Common
92
+
93
+ # This method is a callback method that tries to call all
94
+ # known filtering methods if they are in use.
95
+ #
96
+ # Calling order depends on sets registering order.
97
+ #
98
+ # @return [nil]
99
+ def filter_attributes
100
+ as, fs = *self.class.class_eval { [__attribute_sets, @__filtering_sets] }
101
+ return if fs.blank? || as.blank?
102
+ as.each_pair { |set_name, o| send(fs[set_name]) if fs.has_key?(set_name) }
103
+ nil
104
+ end
105
+
106
+ # Gets a list of filtering hooks that are in use.
107
+ #
108
+ # @return [MetaSet{Symbol => Symbol}] a meta set of filtering methods and associated sets
109
+ def filtering_methods
110
+ f = self.class.instance_variable_get(:@__filtering_sets)
111
+ f.nil? ? ActiveModel::MetaSet.new : f.dup
112
+ end
113
+
114
+ module ClassMethods
115
+ include FilteringRegistration
116
+ end
117
+
72
118
  end # module AttributeFilters
73
119
  end # module ActiveModel