attribute-filters 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +1 -2
- data/.yardopts +1 -1
- data/ChangeLog +188 -0
- data/Manifest.txt +3 -1
- data/README.md +51 -39
- data/attribute-filters.gemspec +3 -3
- data/docs/HISTORY +25 -0
- data/docs/TODO +2 -15
- data/docs/USAGE.md +822 -0
- data/lib/attribute-filters.rb +3 -0
- data/lib/attribute-filters/active_model_insert.rb +2 -1
- data/lib/attribute-filters/attribute_set.rb +21 -1
- data/lib/attribute-filters/attribute_set_attrquery.rb +74 -0
- data/lib/attribute-filters/attribute_set_enum.rb +60 -0
- data/lib/attribute-filters/attribute_set_query.rb +27 -11
- data/lib/attribute-filters/common_filters.rb +76 -1
- data/lib/attribute-filters/dsl_filters.rb +67 -6
- data/lib/attribute-filters/dsl_sets.rb +169 -32
- data/lib/attribute-filters/helpers.rb +14 -0
- data/lib/attribute-filters/railtie.rb +1 -0
- data/lib/attribute-filters/version.rb +2 -1
- data/spec/attribute-filters_spec.rb +39 -12
- data/spec/spec_helper.rb +12 -27
- metadata +32 -30
- metadata.gz.sig +2 -3
- data/docs/USAGE +0 -0
data/lib/attribute-filters.rb
CHANGED
@@ -2,12 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'attribute-filters'
|
4
4
|
require 'attribute-filters/version'
|
5
|
+
require 'attribute-filters/attribute_set_enum'
|
5
6
|
require 'attribute-filters/attribute_set'
|
6
7
|
require 'attribute-filters/attribute_set_query'
|
8
|
+
require 'attribute-filters/attribute_set_attrquery'
|
7
9
|
|
8
10
|
require 'attribute-filters/helpers'
|
9
11
|
require 'attribute-filters/dsl_sets'
|
10
12
|
require 'attribute-filters/dsl_filters'
|
13
|
+
require 'attribute-filters/common_filters'
|
11
14
|
|
12
15
|
if defined? ::Rails
|
13
16
|
require 'attribute-filters/railtie'
|
@@ -8,6 +8,7 @@
|
|
8
8
|
|
9
9
|
require 'active_model'
|
10
10
|
|
11
|
+
# @abstract This namespace is shared with ActveModel.
|
11
12
|
module ActiveModel
|
12
13
|
|
13
14
|
if defined?(AttributeMethods)
|
@@ -30,7 +31,7 @@ module ActiveModel
|
|
30
31
|
singleton_class.send(:alias_method, :included, :included_with_attribute_methods)
|
31
32
|
#singleton_class.send(:alias_method_chain, :included, :attribute_methods)
|
32
33
|
end
|
33
|
-
|
34
|
+
|
34
35
|
end # ActiveModel::AttributeMethods.class_eval
|
35
36
|
|
36
37
|
end # if defined?(AttributeMethods)
|
@@ -12,7 +12,27 @@ require 'set'
|
|
12
12
|
# @abstract This namespace is shared with ActveModel.
|
13
13
|
module ActiveModel
|
14
14
|
# This class is a data structure used to store
|
15
|
-
#
|
15
|
+
# set of attributes.
|
16
16
|
class AttributeSet < ::Set
|
17
|
+
include AttributeSetEnumerable
|
18
|
+
# Adds the given object to the set and returns self.
|
19
|
+
# If the object is already in the set, returns nil.
|
20
|
+
# If the object is an array it adds each element of the array.
|
21
|
+
# The array is not flattened so if it contains other arrays
|
22
|
+
# then they will be added as the arrays.
|
23
|
+
# When adding an array the returning value is also an array,
|
24
|
+
# which contains elements that were successfuly added to set
|
25
|
+
# and didn't existed there before.
|
26
|
+
#
|
27
|
+
# @param o [Object,Array] object to be added to set or array of objects
|
28
|
+
# @return [AttributeSet,nil]
|
29
|
+
def add(o)
|
30
|
+
if o.is_a?(Array)
|
31
|
+
o.map{ |e| super(e) }.compact
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias_method :<<, :add
|
17
37
|
end
|
18
38
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2012 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains ActiveModel::AttributeSet::AttrQuery class
|
8
|
+
# used to interact with attribute sets containing set names.
|
9
|
+
|
10
|
+
# @abstract This namespace is shared with ActveModel.
|
11
|
+
module ActiveModel
|
12
|
+
class AttributeSet
|
13
|
+
# This class contains proxy methods used to interact with
|
14
|
+
# AttributeSet instances. It's responsible for all of the DSL magic
|
15
|
+
# that allows sweet constructs like:
|
16
|
+
# the_attribute(:x).is.in_set?
|
17
|
+
class AttrQuery < Query
|
18
|
+
# This is a proxy method that causes some calls to be
|
19
|
+
# intercepted. Is allows to create semi-natural
|
20
|
+
# syntax when querying attribute sets containing set names.
|
21
|
+
#
|
22
|
+
# When the called method name ends with question mark then
|
23
|
+
# its name is considered to be an attribute set name that
|
24
|
+
# should be tested for presence of the attribute. To use
|
25
|
+
# that syntax you have to be sure that there is no already
|
26
|
+
# defined method for AttributeSet object which name ends
|
27
|
+
# with question mark. Otherwise you may get false positives
|
28
|
+
# or a strange errors when trying to test if attribute belongs
|
29
|
+
# to a set. The real method call will override your check.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# the_attribute(:some_attribute).is.in?(:some_set)
|
33
|
+
# the_attribute(:some_attribute).list.sets
|
34
|
+
# the_attribute(:some_attribute).is.in.a.set.that?(:should_be_downcased)
|
35
|
+
# the_attribute(:some_attribute).should_be_downcased?
|
36
|
+
#
|
37
|
+
# @param method_sym [Symbol,String] name of method that will be queued or called on a set
|
38
|
+
# @param args [Array] optional arguments to be passed to a method call
|
39
|
+
# @yield optional block to be passed to a method call
|
40
|
+
def method_missing(method_sym, *args, &block)
|
41
|
+
case method_sym.to_sym
|
42
|
+
when :are, :is, :one, :is_one, :in, :list, :be, :should,
|
43
|
+
:the, :a, :sets, :in_sets, :set, :in_a_set, :in_set, :belongs_to
|
44
|
+
self
|
45
|
+
when :belongs_to?, :in?, :in_set?, :in_a_set?, :in_the_set?,
|
46
|
+
:the_set?, :set?, :is_one_that?, :one_that?, :that?
|
47
|
+
if args.present? && args.is_a?(::Array)
|
48
|
+
args = args.map{ |a| a.to_sym if a.respond_to?(:to_sym) }
|
49
|
+
end
|
50
|
+
@set_object.include?(*args, &block)
|
51
|
+
else
|
52
|
+
set_name_str = method_sym.to_s.dup
|
53
|
+
if !@set_object.respond_to?(method_sym) && set_name_str.slice!(/\?\z/) == '?'
|
54
|
+
@set_object.include?(set_name_str.to_sym, &block)
|
55
|
+
else
|
56
|
+
@set_object.method(method_sym).call(*args, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
def respond_to?(name)
|
63
|
+
case name.to_sym
|
64
|
+
when :are, :is, :one, :is_one, :in, :list, :be, :should, :the, :a, :sets, :in_sets,
|
65
|
+
:set, :in_a_set, :in_set, :in?, :in_set?, :in_a_set?, :in_the_set?, :the_set?, :set?,
|
66
|
+
:is_one_that?, :one_that?, :that?, :belongs_to?, :belongs_to
|
67
|
+
true
|
68
|
+
else
|
69
|
+
@set_object.respond_to?(name) || name.to_s.slice(-1,1) == '?'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end # class AttrQuery
|
73
|
+
end # class AttributeSet
|
74
|
+
end # module ActiveModel
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2012 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains AttributeSetEnumerable module and AttributeSetEnumerator class.
|
8
|
+
|
9
|
+
# This module adds some enumerable properties to AttributeSet objects.
|
10
|
+
module AttributeSetEnumerable
|
11
|
+
# @private
|
12
|
+
def select
|
13
|
+
if block_given?
|
14
|
+
ActiveModel::AttributeSet.new.tap do |r|
|
15
|
+
each { |e| r << e if yield(e) }
|
16
|
+
end
|
17
|
+
else
|
18
|
+
AttributeSetEnumerator.new(self, :select)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @private
|
23
|
+
def reject
|
24
|
+
if block_given?
|
25
|
+
ActiveModel::AttributeSet.new.tap do |r|
|
26
|
+
each { |e| r << e unless yield(e) }
|
27
|
+
end
|
28
|
+
else
|
29
|
+
AttributeSetEnumerator.new(self, :reject)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def collect
|
35
|
+
if block_given?
|
36
|
+
ActiveModel::AttributeSet.new.tap do |r|
|
37
|
+
each { |e| r << yield(e) }
|
38
|
+
end
|
39
|
+
else
|
40
|
+
AttributeSetEnumerator.new(self, :map)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias_method :map, :collect
|
44
|
+
|
45
|
+
# @private
|
46
|
+
def sort
|
47
|
+
ActiveModel::AttributeSet.new(super)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @private
|
51
|
+
def sort_by
|
52
|
+
ActiveModel::AttributeSet.new(super)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This class adds enumerator for AttributeSet elements.
|
57
|
+
class AttributeSetEnumerator < ::Enumerator
|
58
|
+
include AttributeSetEnumerable
|
59
|
+
end
|
60
|
+
|
@@ -7,6 +7,7 @@
|
|
7
7
|
# This file contains ActiveModel::AttributeSet::Query class
|
8
8
|
# used to interact with attribute sets.
|
9
9
|
|
10
|
+
# @abstract This namespace is shared with ActveModel.
|
10
11
|
module ActiveModel
|
11
12
|
class AttributeSet
|
12
13
|
# This class contains proxy methods used to interact with
|
@@ -16,15 +17,15 @@ module ActiveModel
|
|
16
17
|
class Query < BasicObject
|
17
18
|
# Creates new query object.
|
18
19
|
#
|
19
|
-
# @param
|
20
|
+
# @param set_object [AttributeSet] attribute set for which the query will be made
|
20
21
|
# @param am_object [Object] model object which has access to attributes (may be an instance of ActiveRecord or similar)
|
21
|
-
def initialize(
|
22
|
-
@
|
22
|
+
def initialize(set_object, am_object)
|
23
|
+
@set_object = set_object
|
23
24
|
@am_object = am_object
|
24
25
|
@next_method = nil
|
25
26
|
end
|
26
27
|
|
27
|
-
# This is proxy method that causes some calls to be
|
28
|
+
# This is a proxy method that causes some calls to be
|
28
29
|
# queued to for the next call. Is allows to create semi-natural
|
29
30
|
# syntax when querying attribute sets.
|
30
31
|
#
|
@@ -49,26 +50,41 @@ module ActiveModel
|
|
49
50
|
# @param method_sym [Symbol,String] name of method that will be queued or called on attribute set
|
50
51
|
# @param args [Array] optional arguments to be passed to a method call or to a queued method call
|
51
52
|
# @yield optional block to be passed to a method call or to a queued method call
|
53
|
+
# @return [Object] the returned value is passed back from called method
|
52
54
|
def method_missing(method_sym, *args, &block)
|
53
55
|
case method_sym.to_sym
|
54
56
|
when :are, :is, :be, :should
|
55
57
|
return self
|
56
58
|
end
|
57
|
-
if @
|
59
|
+
if @next_method.nil?
|
58
60
|
case method_sym.to_sym
|
59
|
-
when :all, :any
|
60
|
-
::ActiveModel::AttributeSet::Query.new(@
|
61
|
+
when :all, :any, :none, :one
|
62
|
+
::ActiveModel::AttributeSet::Query.new(@set_object, @am_object). # new obj. == thread-safe
|
61
63
|
next_step(method_sym.to_s << "?", args, block)
|
62
64
|
when :list, :show
|
63
|
-
::ActiveModel::AttributeSet::Query.new(@
|
65
|
+
::ActiveModel::AttributeSet::Query.new(@set_object, @am_object).
|
64
66
|
next_step(:select, args, block)
|
65
67
|
else
|
66
|
-
@
|
68
|
+
r = @set_object.method(method_sym).call(*args, &block)
|
69
|
+
return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
|
70
|
+
::ActiveModel::AttributeSet::Query.new(r, @am_object)
|
67
71
|
end
|
68
72
|
else
|
69
|
-
|
73
|
+
m, args, block = @next_method
|
70
74
|
@next_method = nil
|
71
|
-
@
|
75
|
+
r = @set_object.method(m).call { |a| @am_object[a].method(method_sym).call(*args, &block) }
|
76
|
+
return r if r.respond_to?(:__in_as_proxy) || !r.is_a?(::ActiveModel::AttributeSet)
|
77
|
+
::ActiveModel::AttributeSet::Query.new(r, @am_object)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @private
|
82
|
+
def respond_to?(name)
|
83
|
+
case name.to_sym
|
84
|
+
when :are, :is, :be, :should, :all, :any, :none, :one, :list, :show, :__in_as_proxy
|
85
|
+
true
|
86
|
+
else
|
87
|
+
@set_object.respond_to?(name)
|
72
88
|
end
|
73
89
|
end
|
74
90
|
|
@@ -1,4 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2012 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains ActiveModel::AttributeFilters::Common module
|
8
|
+
# containing ready-to-use, common filtering methods.
|
1
9
|
|
10
|
+
# @abstract This namespace is shared with ActveModel.
|
11
|
+
module ActiveModel
|
12
|
+
module AttributeFilters
|
13
|
+
# This module contains common, ready-to-use filtering methods.
|
14
|
+
module Common
|
15
|
+
# Strips attributes from leading and trailing spaces.
|
16
|
+
#
|
17
|
+
# The attrubutes to be stripped are taken from the attribute set called
|
18
|
+
# +should_be_stripped+. It operates directly on attribute's contents.
|
19
|
+
#
|
20
|
+
# @return [void]
|
21
|
+
def strip_attributes
|
22
|
+
call_attrs_from_set(:should_be_stripped) { |atr| atr.strip! }
|
23
|
+
end
|
2
24
|
|
3
|
-
#
|
25
|
+
# Downcases attributes.
|
26
|
+
#
|
27
|
+
# The attrubutes to be downcased are taken from the attribute set
|
28
|
+
# called +should_be_downcased+. This method is safe to be
|
29
|
+
# used with multibyte strings (containing diacritics).
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
def downcase_attributes
|
33
|
+
filter_attrs_from_set(:should_be_downcased) do |atr|
|
34
|
+
atr.mb_chars.downcase.to_s
|
35
|
+
end
|
36
|
+
end
|
4
37
|
|
38
|
+
# Upcases attributes.
|
39
|
+
#
|
40
|
+
# The attrubutes to be upcased are taken from the attribute set
|
41
|
+
# called +should_be_upcased+. This method is safe to be
|
42
|
+
# used with multibyte strings (containing diacritics).
|
43
|
+
#
|
44
|
+
# @return [void]
|
45
|
+
def upcase_attributes
|
46
|
+
filter_attrs_from_set(:should_be_upcased) do |atr|
|
47
|
+
atr.mb_chars.upcase.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Capitalize attributes.
|
52
|
+
#
|
53
|
+
# The attrubutes to be capitalized are taken from the attribute set
|
54
|
+
# called +should_be_capitalized+. This method is safe to be
|
55
|
+
# used with multibyte strings (containing diacritics).
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
def capitalize_attributes
|
59
|
+
filter_attrs_from_set(:should_be_capitalized) do |atr|
|
60
|
+
atr.mb_chars.capitalize.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Fully capitalize attributes (capitalize each word).
|
65
|
+
#
|
66
|
+
# The attrubutes to be fully capitalized are taken from the attribute set
|
67
|
+
# called +should_be_fully_capitalized+. This method is safe to be
|
68
|
+
# used with multibyte strings (containing diacritics).
|
69
|
+
#
|
70
|
+
# @return [void]
|
71
|
+
def fully_capitalize_attributes
|
72
|
+
filter_attrs_from_set(:should_be_fully_capitalized) do |atr|
|
73
|
+
atr.mb_chars.split(' ').map { |n| n.capitalize }.join(' ')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end # module Common
|
78
|
+
end # module AttributeFilters
|
79
|
+
end # module ActiveModel
|
@@ -6,6 +6,7 @@
|
|
6
6
|
#
|
7
7
|
# This file contains modules with methods that create DSL for managing attribute filters.
|
8
8
|
|
9
|
+
# @abstract This namespace is shared with ActveModel.
|
9
10
|
module ActiveModel
|
10
11
|
module AttributeFilters
|
11
12
|
# @private
|
@@ -20,8 +21,6 @@ module ActiveModel
|
|
20
21
|
# to the given attribute set.
|
21
22
|
#
|
22
23
|
# @param set_name [AttributeSet] set of attributes used to get attributes
|
23
|
-
# @param alter_mode [Boolean] if set then the existence
|
24
|
-
# of attribute is checked by testing if writer is defined; otherwise the reader is checked
|
25
24
|
# @param process_all [Boolean] if set then all the attributes from the attribute set are selected,
|
26
25
|
# not just attributes that has changed
|
27
26
|
# @param no_presence_check [Boolean] if set then the checking whether attribute exists will be
|
@@ -30,9 +29,13 @@ module ActiveModel
|
|
30
29
|
def attributes_to_filter(set_name, process_all = false, no_presence_check = false)
|
31
30
|
atf = attribute_set(set_name)
|
32
31
|
if process_all
|
33
|
-
no_presence_check ? atf : atf & attributes.keys
|
32
|
+
no_presence_check ? atf : atf & (__vatrf(no_presence_check) + attributes.keys)
|
34
33
|
else
|
35
|
-
|
34
|
+
if self.class.filter_virtual_attributes_that_changed?
|
35
|
+
atf & changes.keys
|
36
|
+
else
|
37
|
+
atf & (__vatrf(no_presence_check) + changes.keys)
|
38
|
+
end
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
@@ -46,7 +49,7 @@ module ActiveModel
|
|
46
49
|
# It's major purpose is to create filtering methods.
|
47
50
|
#
|
48
51
|
# Only the
|
49
|
-
# {http://rubydoc.info/gems/activemodel/ActiveModel/Dirty#
|
52
|
+
# {http://rubydoc.info/gems/activemodel/ActiveModel/Dirty#changes-instance_method changed attributes/properties}
|
50
53
|
# are selected, unless the +process_all+ flag is
|
51
54
|
# given. If that flag is given then presence of each attribute is verified,
|
52
55
|
# unless the +no_presence_check+ flag is also set. Attributes with empty or unset values
|
@@ -108,7 +111,7 @@ module ActiveModel
|
|
108
111
|
# It's major purpose is to iterate through attributes and/or work directly with their values.
|
109
112
|
#
|
110
113
|
# Only the
|
111
|
-
# {http://rubydoc.info/gems/activemodel/ActiveModel/Dirty#
|
114
|
+
# {http://rubydoc.info/gems/activemodel/ActiveModel/Dirty#changes-instance_method changed attributes/properties}
|
112
115
|
# are selected, unless the +process_all+ flag is
|
113
116
|
# given. If that flag is given then presence of each attribute is verified,
|
114
117
|
# unless the +no_presence_check+ flag is also set. Attributes with
|
@@ -157,8 +160,56 @@ module ActiveModel
|
|
157
160
|
alias_method :for_attributes_that_are, :for_each_attr_from_set
|
158
161
|
alias_method :for_attributes_which_are, :for_each_attr_from_set
|
159
162
|
|
163
|
+
module ClassMethods
|
164
|
+
# @overload treat_as_real(*attributes)
|
165
|
+
# Informs Attribute Filters that the given attributes
|
166
|
+
# should be treated as present, even they are not in
|
167
|
+
# attributes hash provided by ORM or ActiveModel.
|
168
|
+
# Useful when operating on virtual attributes.
|
169
|
+
#
|
170
|
+
# @param attributes [Array] list of attribute names
|
171
|
+
# @return [void]
|
172
|
+
#
|
173
|
+
# @overload treat_as_real()
|
174
|
+
# Gets the memorized attribute names that should be
|
175
|
+
# treated as existing.
|
176
|
+
#
|
177
|
+
# @return [AttributeSet] set of attribute name
|
178
|
+
def treat_as_real(*args)
|
179
|
+
return __treat_as_real.dup if args.blank?
|
180
|
+
__treat_as_real << args.flatten.compact.map { |atr| atr.to_s }
|
181
|
+
nil
|
182
|
+
end
|
183
|
+
alias_method :treat_attribute_as_real, :treat_as_real
|
184
|
+
alias_method :treat_attributes_as_real, :treat_as_real
|
185
|
+
|
186
|
+
# Sets the internal flag that causes to check virtual attributes
|
187
|
+
# for changes when selecting attributes for filtering.
|
188
|
+
# @return [void]
|
189
|
+
def filter_virtual_attributes_that_have_changed
|
190
|
+
@filter_virtual_attributes_that_changed = true
|
191
|
+
end
|
192
|
+
alias_method :filter_virtual_attributes_that_changed, :filter_virtual_attributes_that_have_changed
|
193
|
+
alias_method :filter_changed_virtual_attributes, :filter_virtual_attributes_that_have_changed
|
194
|
+
|
195
|
+
# Gets the internal flag that causes to check virtual attributes
|
196
|
+
# for changes when selecting attributes for filtering.
|
197
|
+
# @return [Boolean] +true+ if the virtual attributes should be checked for a change, +false+ otherwise
|
198
|
+
def filter_virtual_attributes_that_changed?
|
199
|
+
!!@filter_virtual_attributes_that_changed
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def __treat_as_real
|
205
|
+
@__treat_as_real ||= ActiveModel::AttributeSet.new
|
206
|
+
end
|
207
|
+
|
208
|
+
end # module ClassMethods
|
209
|
+
|
160
210
|
private
|
161
211
|
|
212
|
+
# Applies operations to elements from set.
|
162
213
|
def operate_on_attrs_from_set(set_name, alter_mode, *args, &block)
|
163
214
|
flags = AttributeFiltersHelpers.process_flags(args)
|
164
215
|
process_all = flags[:process_all]
|
@@ -194,5 +245,15 @@ module ActiveModel
|
|
194
245
|
end
|
195
246
|
end
|
196
247
|
|
248
|
+
private
|
249
|
+
|
250
|
+
# Helper that collects virtual attributes that
|
251
|
+
# have setters and getters.
|
252
|
+
def __vatrf(no_presence_check = false)
|
253
|
+
tar = self.class.send(:__treat_as_real)
|
254
|
+
return tar if no_presence_check || tar.empty?
|
255
|
+
tar.select { |a| respond_to?(a) && respond_to?("#{a}=") }
|
256
|
+
end
|
257
|
+
|
197
258
|
end # module AttributeFilters
|
198
259
|
end # module ActiveModel
|