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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 584f98e3ee0d6805aeeb6ad6b93403c0385c6ee5
4
- data.tar.gz: 864b63c2631cd805b72c4f513a095b312aad4177
3
+ metadata.gz: 2d895597b76cd8b4d0264a01a1edbd02dae18d12
4
+ data.tar.gz: aef0a1676a11b7a1d6d9c802415d52c976913342
5
5
  SHA512:
6
- metadata.gz: f261c86808b820ad41ace486d0bec69379bdbad03529c42451eece0888039e034e3af3778b5b946bd9dc6797f4049087b3099618bd71b5e61b30b93d9f54466f
7
- data.tar.gz: a480f9e5ea51d9ac98922194b9cfecf124b410c2a5226851bf1fdb7ad9b592830f24345de591d4951b4f3a3327afe86596f5fb0095418932f5ef28814a322541
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
- association_list.preload(*inner_associations)
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
- association_list.preload(*inner_associations)
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 assocation type: '#{assocation}'")
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, [v])
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
@@ -1,5 +1,5 @@
1
1
  module Ar
2
2
  module Preloader
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-preloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajith Hussain