Class: RPCMapper::Relation
Overview
TRP: The concepts behind this class are heavily influenced by ActiveRecord::Relation v.3.0.0RC1
Used to achieve the chainability of scopes – methods are delegated back and forth from BM::Base and BM::Relation
Constant Summary
collapse
- SINGLE_VALUE_METHODS =
[:limit, :offset, :from, :fresh]
- MULTI_VALUE_METHODS =
[:select, :group, :order, :joins, :includes, :where, :having]
- FINDER_OPTIONS =
SINGLE_VALUE_METHODS + MULTI_VALUE_METHODS + [:conditions, :search, :sql]
Instance Attribute Summary collapse
Attributes included from QueryMethods
#fresh_value, #from_value, #group_values, #having_values, #includes_values, #joins_values, #limit_value, #offset_value, #order_values, #raw_sql_value, #select_values, #where_values
Instance Method Summary
collapse
#all, #apply_finder_options, #find, #first, #search
#fresh, #from, #group, #having, #includes, #joins, #limit, #offset, #order, #select, #sql, #where
Constructor Details
#initialize(klass) ⇒ Relation
Returns a new instance of Relation.
17
18
19
20
21
22
|
# File 'lib/rpc_mapper/relation.rb', line 17
def initialize(klass)
@klass = klass
SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
MULTI_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_values", [])}
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/rpc_mapper/relation.rb', line 104
def method_missing(method, *args, &block)
if Array.method_defined?(method)
to_a.send(method, *args, &block)
elsif result = dynamic_finder_method(method)
method, attribute = result
options = { :conditions => { attribute => args[0] } }
options.merge!(args[1]) if args[1] && args[1].is_a?(Hash)
case method.to_sym
when :find_by
self.first(options)
when :find_all_by
self.all(options)
end
elsif @klass.scopes[method]
merge(@klass.send(method, *args, &block))
elsif @klass.respond_to?(method, false)
scoping { @klass.send(method, *args, &block) }
else
super
end
end
|
Instance Attribute Details
#klass ⇒ Object
Returns the value of attribute klass.
8
9
10
|
# File 'lib/rpc_mapper/relation.rb', line 8
def klass
@klass
end
|
Instance Method Details
#dynamic_finder_method(method) ⇒ Object
93
94
95
96
97
98
99
100
|
# File 'lib/rpc_mapper/relation.rb', line 93
def dynamic_finder_method(method)
defined_attributes = (@klass.defined_attributes || []).join('|')
if method.to_s =~ /^(find_by|find_all_by)_(#{defined_attributes})/
[$1, $2]
else
nil
end
end
|
#eager_load? ⇒ Boolean
68
69
70
|
# File 'lib/rpc_mapper/relation.rb', line 68
def eager_load?
@includes_values && !@includes_values.empty?
end
|
#inspect ⇒ Object
72
73
74
|
# File 'lib/rpc_mapper/relation.rb', line 72
def inspect
to_a.inspect
end
|
#merge(r) ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/rpc_mapper/relation.rb', line 24
def merge(r)
merged_relation = clone
return merged_relation unless r
SINGLE_VALUE_METHODS.each do |option|
new_value = r.send("#{option}_value")
merged_relation = merged_relation.send(option, new_value) if new_value
end
MULTI_VALUE_METHODS.each do |option|
merged_relation = merged_relation.send(option, *r.send("#{option}_values"))
end
merged_relation
end
|
#respond_to?(method, include_private = false) ⇒ Boolean
85
86
87
88
89
90
91
|
# File 'lib/rpc_mapper/relation.rb', line 85
def respond_to?(method, include_private=false)
super ||
Array.method_defined?(method) ||
@klass.scopes[method] ||
dynamic_finder_method(method) ||
@klass.respond_to?(method, false)
end
|
#scoping ⇒ Object
76
77
78
79
80
81
82
83
|
# File 'lib/rpc_mapper/relation.rb', line 76
def scoping
@klass.scoped_methods << self
begin
yield
ensure
@klass.scoped_methods.pop
end
end
|
#to_a ⇒ Object
64
65
66
|
# File 'lib/rpc_mapper/relation.rb', line 64
def to_a
@records ||= fetch_records
end
|
#to_hash ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/rpc_mapper/relation.rb', line 40
def to_hash
@hash ||= if self.raw_sql_value
{ :sql => raw_sql_value }
else
hash = SINGLE_VALUE_METHODS.inject({}) do |h, option|
value = self.send("#{option}_value")
value ? h.merge(option => value) : h
end
hash.merge!((MULTI_VALUE_METHODS - [:select]).inject({}) do |h, option|
value = self.send("#{option}_values")
value && !value.empty? ? h.merge(option => value.uniq) : h
end)
if select_values && !select_values.empty? && !select_values.any? { |val| val.to_s.match(/\*$/) }
hash.merge!(:select => select_values.uniq)
end
hash
end
end
|