ar-preloader 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ar/preloader.rb +76 -10
- data/lib/ar/preloader/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d895597b76cd8b4d0264a01a1edbd02dae18d12
|
4
|
+
data.tar.gz: aef0a1676a11b7a1d6d9c802415d52c976913342
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baf8de3beb914d202cb72431db24a71ccb0844d97353ce06211450aa2bebcc2d522ef43b83ea0dc52314378d0626966b1e720de409b8b8c796bc1381ca05ecd4
|
7
|
+
data.tar.gz: a7407f60a72dfacb079ac3426f0d97a39bc2b84050a8a211a12cf41899c202d4085edb600c6302770f93b2842c4de99773483223c7b1a88e760b7b54bf473bcb
|
data/lib/ar/preloader.rb
CHANGED
@@ -9,6 +9,10 @@ module Ar
|
|
9
9
|
case association
|
10
10
|
when String, Symbol
|
11
11
|
return klass.reflections.keys.include?(association.to_s)
|
12
|
+
when Array
|
13
|
+
association.each do |v|
|
14
|
+
return false unless Ar::Preloader.check_association_exists(klass, v)
|
15
|
+
end
|
12
16
|
when Hash
|
13
17
|
association.each_pair do |k,v|
|
14
18
|
return false unless klass.reflections.keys.include?(k.to_s)
|
@@ -38,6 +42,8 @@ module Ar
|
|
38
42
|
case association
|
39
43
|
when String, Symbol
|
40
44
|
klass = list.first.class
|
45
|
+
klass.send :attr_reader, "_#{association}".to_sym
|
46
|
+
|
41
47
|
association_details = klass.reflections[association.to_s]
|
42
48
|
association_klass = association_details.class_name.constantize
|
43
49
|
|
@@ -46,6 +52,11 @@ module Ar
|
|
46
52
|
foreign_key = association_details.foreign_key
|
47
53
|
association_pk = association_klass.primary_key
|
48
54
|
|
55
|
+
list.each do |obj|
|
56
|
+
instance_variable_name = "@_#{association}".to_sym
|
57
|
+
obj.instance_variable_set(instance_variable_name, [])
|
58
|
+
end
|
59
|
+
|
49
60
|
query = <<-EOS
|
50
61
|
SELECT
|
51
62
|
distinct #{association_klass.table_name}.*
|
@@ -56,15 +67,14 @@ EOS
|
|
56
67
|
|
57
68
|
association_list = association_klass.find_by_sql(query).to_a
|
58
69
|
|
59
|
-
|
70
|
+
if inner_associations.is_a?(Array)
|
71
|
+
association_list.preload(*inner_associations)
|
72
|
+
else
|
73
|
+
association_list.preload(inner_associations)
|
74
|
+
end
|
60
75
|
|
61
76
|
list.each do |obj|
|
62
|
-
klass.send :attr_reader, "_#{association}".to_sym
|
63
|
-
|
64
77
|
instance_variable_name = "@_#{association}".to_sym
|
65
|
-
if obj.instance_variable_get(instance_variable_name).nil?
|
66
|
-
obj.instance_variable_set(instance_variable_name, [])
|
67
|
-
end
|
68
78
|
|
69
79
|
association_list.select{ |e| e[foreign_key.to_sym] == obj[klass.primary_key.to_sym] }.each do |association_obj|
|
70
80
|
each_list = obj.instance_variable_get(instance_variable_name)
|
@@ -76,6 +86,10 @@ EOS
|
|
76
86
|
foreign_key = association_details.foreign_key
|
77
87
|
association_pk = association_klass.primary_key
|
78
88
|
|
89
|
+
if list.map{ |e| e[foreign_key.to_sym] }.compact.length == 0
|
90
|
+
return true
|
91
|
+
end
|
92
|
+
|
79
93
|
query = <<-EOS
|
80
94
|
SELECT
|
81
95
|
distinct #{association_klass.table_name}.*
|
@@ -86,22 +100,73 @@ EOS
|
|
86
100
|
|
87
101
|
association_list = association_klass.find_by_sql(query).to_a
|
88
102
|
|
89
|
-
|
103
|
+
if inner_associations.is_a?(Array)
|
104
|
+
association_list.preload(*inner_associations)
|
105
|
+
else
|
106
|
+
association_list.preload(inner_associations)
|
107
|
+
end
|
90
108
|
|
91
109
|
association_map = association_list.map{ |e| [e[e.class.primary_key.to_sym], e] }.to_h
|
92
110
|
|
93
111
|
list.each do |obj|
|
94
112
|
if obj[foreign_key.to_sym].present? && association_map[obj[foreign_key.to_sym]].present?
|
95
|
-
klass.send :attr_reader, "_#{association}".to_sym
|
96
113
|
obj.instance_variable_set( "@_#{association}".to_sym, association_map[obj[foreign_key.to_sym]] )
|
97
114
|
end
|
98
115
|
end
|
116
|
+
when ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
117
|
+
foreign_key = association_details.foreign_key
|
118
|
+
association_foreign_key = association_details.association_foreign_key
|
119
|
+
join_table = association_details.join_table
|
120
|
+
|
121
|
+
list.each do |obj|
|
122
|
+
instance_variable_name = "@_#{association}".to_sym
|
123
|
+
obj.instance_variable_set(instance_variable_name, [])
|
124
|
+
end
|
125
|
+
|
126
|
+
join_query = <<-EOS
|
127
|
+
SELECT
|
128
|
+
#{join_table}.#{foreign_key},
|
129
|
+
#{join_table}.#{association_foreign_key}
|
130
|
+
FROM #{join_table}
|
131
|
+
WHERE #{join_table}.#{foreign_key} IN (#{ list.map{ |e| e[klass.primary_key.to_sym].try(:to_s) }.compact.join(",") })
|
132
|
+
|
133
|
+
EOS
|
134
|
+
join_entries = ActiveRecord::Base.connection.execute(join_query).to_a
|
135
|
+
|
136
|
+
query = <<-EOS
|
137
|
+
SELECT
|
138
|
+
distinct #{association_klass.table_name}.*
|
139
|
+
FROM #{association_klass.table_name}
|
140
|
+
INNER JOIN #{join_table} ON #{join_table}.#{association_foreign_key} = #{association_klass.table_name}.#{association_klass.primary_key}
|
141
|
+
WHERE #{join_table}.#{foreign_key} IN (#{ list.map{ |e| e[klass.primary_key.to_sym].try(:to_s) }.compact.join(",") })
|
142
|
+
|
143
|
+
EOS
|
144
|
+
|
145
|
+
association_list = association_klass.find_by_sql(query).to_a
|
146
|
+
|
147
|
+
if inner_associations.is_a?(Array)
|
148
|
+
association_list.preload(*inner_associations)
|
149
|
+
else
|
150
|
+
association_list.preload(inner_associations)
|
151
|
+
end
|
152
|
+
|
153
|
+
list.each do |obj|
|
154
|
+
instance_variable_name = "@_#{association}".to_sym
|
155
|
+
|
156
|
+
association_key_list = join_entries.select{ |e| e[0] == obj[klass.primary_key.to_s] }.map(&:last)
|
157
|
+
|
158
|
+
association_list.select{ |e| association_key_list.include?( e[association_klass.primary_key.to_s] ) }.each do |association_obj|
|
159
|
+
each_list = obj.instance_variable_get(instance_variable_name)
|
160
|
+
each_list << association_obj
|
161
|
+
obj.instance_variable_set(instance_variable_name, each_list)
|
162
|
+
end
|
163
|
+
end
|
99
164
|
else
|
100
|
-
raise Ar::Preloader::Error.new("Unsupported
|
165
|
+
raise Ar::Preloader::Error.new("Unsupported association type: '#{association}'")
|
101
166
|
end
|
102
167
|
when Hash
|
103
168
|
association.each_pair do |k,v|
|
104
|
-
Ar::Preloader.preload_association(list, k,
|
169
|
+
Ar::Preloader.preload_association(list, k, v)
|
105
170
|
end
|
106
171
|
end
|
107
172
|
end
|
@@ -115,6 +180,7 @@ class Array
|
|
115
180
|
raise Ar::Preloader::Error.new("Cannot preload. Mixed type lists are not supported.") if (self.map(&:class).uniq.count > 1)
|
116
181
|
raise Ar::Preloader::Error.new("Cannot preload. At least one element in array is not an ActiveRecord object.") if (self.reject{|e| e.is_a?(ActiveRecord::Base) }.count > 0)
|
117
182
|
|
183
|
+
|
118
184
|
args.each do |arg|
|
119
185
|
raise Ar::Preloader::Error.new("Cannot find association '#{arg}' on one or more of the ActiveRecord objects.") if (self.reject{|e| Ar::Preloader.check_association_exists(e.class, arg) }.count > 0)
|
120
186
|
end
|
data/lib/ar/preloader/version.rb
CHANGED