ar_lazy_preload 2.1.0 → 2.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82d5aeed661b9ab42f1d15f78cb8db84cc8b426ddfe26ae1442f297800ec0707
4
- data.tar.gz: 1c89c0b2f8025143186551e06629c40a37bf8c207b7605c71481b02c158f89f5
3
+ metadata.gz: 927bf2110e3c5733916353191cbc1c1b9543dab216b6aef4b120cd6383822796
4
+ data.tar.gz: 24e78260d612a9d212c4b53937abff9cf6f68e32aa5728c60b4d686ea49efcf8
5
5
  SHA512:
6
- metadata.gz: acbedff3a73e2b26ee0a905c9b5059e9e27297abccd2a16c0a68c3bd67001a4d45721b83aaad21738b36d6c7bce8d41ea6756bd0f1bd54973f339ab2cc26ea68
7
- data.tar.gz: 5285e4116f8ba49bc7aa2cbfc1962bfff112785ebd7dbed823ebadf606e9eef1f0772f7f30312344a00cbe8c76af37fc0378d422933073d8758bebe5ae6bcd85
6
+ metadata.gz: 88ca2ecb46671b3ec6f671d06c540a24bbcade260d68309993d2049e76730926b173074b3255cafc51e2d4e8636f5b7a3fbf4b17c1c838b5a4935c0545ffbf81
7
+ data.tar.gz: 5266eb7b7901631633a4c8ee554935c29757c60955f2749910ffd2e3688bc66a30edd330e9703c7775020868a0836f8d181cd6ed1f357719098f04a4791a437c
data/README.md CHANGED
@@ -13,6 +13,8 @@ Used in production by:
13
13
  - Toptal
14
14
  - _Want to be here? Let me know_ 🙂
15
15
 
16
+ You can support my open–source work [here](https://boosty.to/dmitry_tsepelev).
17
+
16
18
  ## Why should I use it?
17
19
 
18
20
  Lazy loading is super helpful when the list of associations to load is determined dynamically. For instance, in GraphQL this list comes from the API client, and you'll have to inspect the selection set to find out what associations are going to be used.
@@ -76,6 +78,8 @@ posts = User.preload_associations_lazily.flat_map(&:posts)
76
78
 
77
79
  3. Lazy preloading for **ActiveStorage** variants is not working automatically because of the way how it is implemented ([here](https://github.com/DmitryTsepelev/ar_lazy_preload/pull/70) is the issue). You can preload them manually by calling `#with_all_variant_records`/`#with_attached_#{attachment_name}` on association. Example: `User.with_attached_avatar.first(10).map { |u| u.avatar.variant(:small).processed.url }`
78
80
 
81
+ 4. Lazy preloading does not work for association object creation methods, so it is better if you separate the logic for writing and reading objects and use lazy preloading for read only, more information with example [here](https://github.com/DmitryTsepelev/ar_lazy_preload/issues/75)
82
+
79
83
  ## Installation
80
84
 
81
85
  Add this line to your application's Gemfile, and you're all set:
@@ -52,12 +52,65 @@ module ArLazyPreload
52
52
  preload_records(association_name, filtered_records)
53
53
  loaded_association_names.add(association_name)
54
54
 
55
+ # Prepare context for intermediate through associations
56
+ prepare_through_association_contexts(association_name, filtered_records)
57
+
55
58
  AssociatedContextBuilder.prepare(
56
59
  parent_context: self,
57
60
  association_name: association_name
58
61
  )
59
62
  end
60
63
 
64
+ # Prepare context for intermediate associations in through chains
65
+ def prepare_through_association_contexts(association_name, filtered_records)
66
+ filtered_records.group_by(&:class).each do |klass, klass_records|
67
+ chain = through_association_chain(association_name, klass)
68
+ next if chain.empty?
69
+
70
+ chain.each do |intermediate_name|
71
+ register_intermediate_context(klass, klass_records, intermediate_name)
72
+ end
73
+ end
74
+ end
75
+
76
+ def register_intermediate_context(klass, klass_records, intermediate_name)
77
+ return if association_loaded?(intermediate_name)
78
+
79
+ reflection = klass.reflect_on_association(intermediate_name)
80
+ return if reflection.nil?
81
+
82
+ loaded_association_names.add(intermediate_name)
83
+
84
+ intermediate_records = collect_intermediate_records(klass_records, reflection)
85
+ return if intermediate_records.empty?
86
+
87
+ ArLazyPreload::Context.register(records: intermediate_records, auto_preload: true)
88
+ end
89
+
90
+ def collect_intermediate_records(klass_records, reflection)
91
+ klass_records.flat_map do |record|
92
+ record_association = record.association(reflection.name)
93
+ reflection.collection? ? record_association.target : record_association.reader
94
+ end.compact
95
+ end
96
+
97
+ # Extract chain of intermediate association names for through associations
98
+ def through_association_chain(association_name, klass)
99
+ reflection = klass.reflect_on_association(association_name)
100
+ return [] unless reflection&.options&.key?(:through)
101
+
102
+ chain = []
103
+ current_reflection = reflection
104
+
105
+ while current_reflection&.options&.key?(:through)
106
+ through_name = current_reflection.options[:through]
107
+ chain.unshift(through_name)
108
+ current_reflection = klass.reflect_on_association(through_name)
109
+ end
110
+
111
+ chain
112
+ end
113
+
61
114
  # Method preloads associations for the specific sets of the records
62
115
  # and provides automatically provides context for the records
63
116
  # loaded using `includes` inside Relation#preload_associations with the
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArLazyPreload
4
- VERSION = "2.1.0"
4
+ VERSION = "2.1.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_lazy_preload
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-03-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '6.1'
18
+ version: '7.0'
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '6.1'
25
+ version: '7.0'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: rspec
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -109,19 +108,19 @@ dependencies:
109
108
  - !ruby/object:Gem::Version
110
109
  version: '0'
111
110
  - !ruby/object:Gem::Dependency
112
- name: database_cleaner
111
+ name: database_cleaner-active_record
113
112
  requirement: !ruby/object:Gem::Requirement
114
113
  requirements:
115
- - - ">="
114
+ - - '='
116
115
  - !ruby/object:Gem::Version
117
- version: '0'
116
+ version: 2.2.1
118
117
  type: :development
119
118
  prerelease: false
120
119
  version_requirements: !ruby/object:Gem::Requirement
121
120
  requirements:
122
- - - ">="
121
+ - - '='
123
122
  - !ruby/object:Gem::Version
124
- version: '0'
123
+ version: 2.2.1
125
124
  - !ruby/object:Gem::Dependency
126
125
  name: factory_bot
127
126
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +177,34 @@ dependencies:
178
177
  - - ">="
179
178
  - !ruby/object:Gem::Version
180
179
  version: '0'
180
+ - !ruby/object:Gem::Dependency
181
+ name: benchmark
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ - !ruby/object:Gem::Dependency
195
+ name: ostruct
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ type: :development
202
+ prerelease: false
203
+ version_requirements: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
181
208
  description: lazy_preload implementation for ActiveRecord models
182
209
  email:
183
210
  - dmitry.a.tsepelev@gmail.com
@@ -212,7 +239,6 @@ homepage: https://github.com/DmitryTsepelev/ar_lazy_preload
212
239
  licenses:
213
240
  - MIT
214
241
  metadata: {}
215
- post_install_message:
216
242
  rdoc_options: []
217
243
  require_paths:
218
244
  - lib
@@ -227,8 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
253
  - !ruby/object:Gem::Version
228
254
  version: '0'
229
255
  requirements: []
230
- rubygems_version: 3.4.10
231
- signing_key:
256
+ rubygems_version: 4.0.3
232
257
  specification_version: 4
233
258
  summary: lazy_preload implementation for ActiveRecord models
234
259
  test_files: []