mm_eager_includer 0.0.3 → 0.0.4

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 (3) hide show
  1. checksums.yaml +5 -13
  2. data/lib/mongo_mapper/eager_includer.rb +89 -118
  3. metadata +6 -5
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmYxZGE3OWFjNWQ4YzFlYjUzYWMxNzJkZmExMmExM2Y3NjIzZDFkNQ==
5
- data.tar.gz: !binary |-
6
- ZGU3NmMyMjMyYWFiNWI4N2UzOGY4NzI5OTJiMWQ4ZGNkOGEzODI4Zg==
2
+ SHA1:
3
+ metadata.gz: 7332631d4be05cc147356b553f3c0c64fd0c9ac0
4
+ data.tar.gz: fca0a9ad9712a1b1ec7a7d6018d38949ea85bc8d
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OGZmNzcwNzYwZWQ5NzdhZTU2YzlhMGFkMGNmN2NlMDQzNGQ3MTVhNjE5NDNm
10
- MDk0MTZhNmQ2ZTJkZDdiMTY1ODFhNWExN2VmY2NiZmYxYjZlYjNlYjdhZGUy
11
- NmQwMTE3OTkxMjljNmMyNTJkMDczZDQxNDgwNTczZTRkYzRhY2Y=
12
- data.tar.gz: !binary |-
13
- NWQ0YzY5NjU3MDM4NDVjMTUwZjVlYzc1ZGVmOGJkNGZjODgwZDQ4ZWY1Mzlk
14
- YTAzMWI0ZmM1MDZhNTE1NjJhODQ3MmFiNDY1MjcxMTViMGY1OTg2N2E5NGY3
15
- OWViZmVhNWY0YmU5ODc0MjczNzkxMjhjMTdjZmViZjc3ZjM2ZjM=
6
+ metadata.gz: 1528a173b37634d5e4f27969344be8ab26b990ae3f61cbee9b46f9c7ec29cad335be327453825d686295cc836c08d568ecb99bfa40cfb46b63d83b0585850732
7
+ data.tar.gz: b5fc7442713502e7bf4b4995a312668818c9edd9d6c7c2644b5d127a181be6e09e92e3341d19e72836cfbe623909dc160f24648a4346d3fb8e40b024a2786d40
@@ -1,122 +1,119 @@
1
1
  require 'mongo_mapper'
2
2
 
3
3
  class MongoMapper::EagerIncluder
4
- class << self
5
- def enabled?
6
- (@enabled == true || @enabled == false) ? @enabled : true
7
- end
8
-
9
- def enabled=(bool)
10
- @enabled = bool
11
- end
12
-
13
- def eager_include(record_or_records, *association_names, &block)
14
- association_names.each do |association_name|
15
- new(record_or_records, association_name).eager_include(&block)
16
- end
17
- end
18
-
19
- def write_to_cache(object_id, association_name, value)
20
- cache[association_name] ||= {}
21
- cache[association_name][object_id] = value
22
- end
23
-
24
- def read_from_cache(object_id, association_name)
25
- cache[association_name][object_id]
26
- end
27
-
28
- def clear_cache!
29
- @cache = {}
30
- end
31
-
32
- private
33
-
34
- def cache
35
- @cache ||= {}
4
+ def self.eager_include(record_or_records, *association_names, &query_alteration_block)
5
+ association_names.each do |association_name|
6
+ new(record_or_records, association_name, &query_alteration_block).eager_include
36
7
  end
37
8
  end
38
9
 
39
- def initialize(record_or_records, association_name)
40
- association_name = association_name.to_sym
41
-
42
- @records = Array(record_or_records)
43
-
44
- if @records.length == 0
45
- return
10
+ def initialize(record_or_records, association_name, &query_alteration_block)
11
+ if record_or_records.is_a? Plucky::Query
12
+ raise "You must call `to_a` on `Plucky::Query` objects before passing to eager_include"
46
13
  end
14
+ @records = Array(record_or_records)
47
15
 
16
+ return if @records.length == 0
48
17
  @association_name = association_name.to_sym
49
- @association = @records.first.associations[association_name]
18
+ @query_alteration_block = query_alteration_block
19
+ @association = @records.first.associations[@association_name]
50
20
  if !@association
51
21
  raise "Could not find association `#{association_name}` on instance of #{@records.first.class}"
52
22
  end
53
-
54
- @proxy_class = @association.proxy_class
55
23
  end
56
24
 
57
- def enabled?
58
- self.class.enabled?
59
- end
60
-
61
- def eager_include(&block)
62
- return if !enabled?
63
-
64
- if @records.length == 0
65
- return
25
+ def eager_include
26
+ @records.reject! do |record|
27
+ record.instance_variable_defined?(instance_variable_name)
66
28
  end
67
29
 
68
- if @proxy_class == MongoMapper::Plugins::Associations::ManyDocumentsProxy
69
- eager_include_has_many(&block)
70
- elsif @proxy_class == MongoMapper::Plugins::Associations::BelongsToProxy
71
- eager_include_belongs_to(&block)
72
- elsif @proxy_class == MongoMapper::Plugins::Associations::OneProxy
73
- eager_include_has_one(&block)
74
- elsif @proxy_class == MongoMapper::Plugins::Associations::InArrayProxy
75
- eager_include_has_many_in(&block)
30
+ return if @records.length == 0
31
+
32
+ @association_type = case @association.proxy_class.to_s
33
+ when 'MongoMapper::Plugins::Associations::ManyDocumentsProxy'
34
+ :has_many
35
+ when 'MongoMapper::Plugins::Associations::BelongsToProxy'
36
+ :belongs_to
37
+ when 'MongoMapper::Plugins::Associations::OneProxy'
38
+ :has_one
39
+ when 'MongoMapper::Plugins::Associations::InArrayProxy'
40
+ :has_many_in
76
41
  else
77
- raise NotImplementedError, "#{@proxy_class} not supported yet!"
42
+ raise NotImplementedError, "#{@association.proxy_class} not supported yet!"
78
43
  end
44
+
45
+ send("eager_include_#{@association_type}")
79
46
  end
80
47
 
81
48
  private
82
49
 
83
- def setup_association(record, association_name, value)
84
- association_name = association_name.to_sym
50
+ attr_reader :association_name
85
51
 
86
- self.class.write_to_cache(record.object_id, association_name, value)
52
+ def instance_variable_name
53
+ "@eager_loaded_#{association_name}"
54
+ end
87
55
 
88
- code = <<-CODE
56
+ def setup_association(record, value)
57
+ code = <<-RUBY
89
58
  def #{association_name}
90
- MongoMapper::EagerIncluder.read_from_cache(object_id, :#{association_name})
59
+ #{instance_variable_name}
91
60
  end
92
- CODE
93
-
61
+ RUBY
94
62
  record.instance_eval(code, __FILE__, __LINE__)
63
+ record.instance_variable_set(instance_variable_name, value)
64
+ end
65
+
66
+ def association_class
67
+ @association_class ||= @association.klass
95
68
  end
96
69
 
97
70
  def foreign_keys
98
- @association.options[:in]
71
+ @foreign_keys ||= @association.options[:in]
99
72
  end
100
73
 
101
74
  def foreign_key
102
- @association_name.to_s.foreign_key
75
+ @foreign_key ||= @association_name.to_s.foreign_key
103
76
  end
104
77
 
105
78
  def primary_key
106
- @association.options[:foreign_key] || @records.first.class.name.foreign_key
79
+ @primary_key ||= @association.options[:foreign_key] || @records.first.class.name.foreign_key
80
+ end
81
+
82
+ def record_ids
83
+ case @association_type
84
+ when :has_many, :has_one
85
+ @records.map(&:id)
86
+ when :belongs_to
87
+ @records.map do |record|
88
+ record.send(foreign_key)
89
+ end
90
+ when :has_many_in
91
+ @records.map do |record|
92
+ record.send(foreign_keys)
93
+ end.flatten
94
+ end.uniq
95
+ end
96
+
97
+ def load_association_records!
98
+ @association_records_query = case @association_type
99
+ when :has_many, :has_one
100
+ association_class.where({ primary_key => { '$in' => record_ids } })
101
+ when :belongs_to, :has_many_in
102
+ association_class.where({ _id: { '$in' => record_ids } })
103
+ end
104
+
105
+ if @query_alteration_block
106
+ @association_records_query = @query_alteration_block.call(@association_records_query)
107
+ end
108
+ @association_records = @association_records_query.all
107
109
  end
108
110
 
109
111
  def eager_include_has_many(&block)
110
- ids = @records.map { |el| el.id }.uniq
111
- proxy_records = @association.klass.where({
112
- primary_key => {
113
- '$in' => ids
114
- }
115
- }).all
112
+ load_association_records!
116
113
 
117
114
  @records.each do |record|
118
- matching_proxy_records = proxy_records.select do |proxy_record|
119
- record_or_records = proxy_record.send(primary_key)
115
+ matching_association_records = @association_records.select do |association_record|
116
+ record_or_records = association_record.send(primary_key)
120
117
  if record_or_records.is_a?(Array)
121
118
  record_or_records.include?(record.id)
122
119
  else
@@ -124,71 +121,45 @@ private
124
121
  end
125
122
  end
126
123
 
127
- setup_association(record, @association_name, matching_proxy_records)
124
+ setup_association(record, matching_association_records)
128
125
  end
129
126
  end
130
127
 
131
128
  def eager_include_has_one(&block)
132
- ids = @records.map { |el| el.id }.uniq
133
- proxy_records = @association.klass.where({
134
- primary_key => ids
135
- })
136
-
137
- if block
138
- proxy_records = block.call(proxy_records)
139
- end
140
-
141
- proxy_records = proxy_records.all
129
+ load_association_records!
142
130
 
143
131
  @records.each do |record|
144
- matching_proxy_record = proxy_records.detect do |proxy_record|
145
- proxy_record.send(primary_key) == record.id
132
+ matching_association_record = @association_records.detect do |association_record|
133
+ association_record.send(primary_key) == record.id
146
134
  end
147
135
 
148
- setup_association(record, @association_name, matching_proxy_record)
136
+ setup_association(record, matching_association_record)
149
137
  end
150
138
  end
151
139
 
152
140
  def eager_include_belongs_to(&block)
153
- ids = @records.map { |el| el.send(foreign_key) }.uniq
154
-
155
- proxy_records = @association.klass.where({
156
- :_id => {
157
- '$in' => ids
158
- }
159
- })
160
-
161
- if block
162
- proxy_records = block.call(proxy_records)
163
- end
164
-
165
- proxy_records = proxy_records.all
141
+ load_association_records!
166
142
 
167
143
  @records.each do |record|
168
- matching_proxy_record = proxy_records.detect do |proxy_record|
169
- proxy_record.id == record.send(foreign_key)
144
+ matching_association_record = @association_records.detect do |association_record|
145
+ association_record.id == record.send(foreign_key)
170
146
  end
171
147
 
172
- setup_association(record, @association_name, matching_proxy_record)
148
+ setup_association(record, matching_association_record)
173
149
  end
174
150
  end
175
151
 
176
152
  def eager_include_has_many_in(&block)
177
- ids = @records.map { |el| el.send(foreign_keys) }.flatten.uniq
178
- proxy_records = @association.klass.where({
179
- '_id' => {
180
- '$in' => ids
181
- }
182
- }).all
153
+ load_association_records!
183
154
 
184
155
  @records.each do |record|
185
- proxy_record_ids = record.send(foreign_keys)
156
+ association_record_ids = record.send(foreign_keys)
186
157
 
187
- matching_proxy_records = proxy_record_ids.map do |proxy_record_id|
188
- proxy_records.detect { |proxy_record| proxy_record.id == proxy_record_id }
158
+ matching_association_records = association_record_ids.map do |association_record_id|
159
+ @association_records.detect { |association_record| association_record.id == association_record_id }
189
160
  end
190
161
 
191
- setup_association(record, @association_name, matching_proxy_records)
162
+ setup_association(record, matching_association_records)
192
163
  end
193
164
  end
194
165
  end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mm_eager_includer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Taylor
8
8
  - Andrew Pariser
9
+ - Jared Grippe
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-05-05 00:00:00.000000000 Z
13
+ date: 2016-05-09 00:00:00.000000000 Z
13
14
  dependencies: []
14
15
  description: Eager include associations with mongo mapper
15
16
  email: scott@railsnewbie.com
@@ -28,17 +29,17 @@ require_paths:
28
29
  - lib
29
30
  required_ruby_version: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ! '>='
32
+ - - ">="
32
33
  - !ruby/object:Gem::Version
33
34
  version: '0'
34
35
  required_rubygems_version: !ruby/object:Gem::Requirement
35
36
  requirements:
36
- - - ! '>='
37
+ - - ">="
37
38
  - !ruby/object:Gem::Version
38
39
  version: '0'
39
40
  requirements: []
40
41
  rubyforge_project:
41
- rubygems_version: 2.4.5
42
+ rubygems_version: 2.4.8
42
43
  signing_key:
43
44
  specification_version: 4
44
45
  summary: Eager include associations with mongo mapper