predictive_load 0.5.1 → 0.7.0

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: 4b0c3352a1804088cd709d17e619ff406cc243a92ef5b180815416e704b89775
4
- data.tar.gz: b12b98881fccee776a2cf2175a8c2d4c06eb6325d1d5a47c08a732f5b6c2eb51
3
+ metadata.gz: 93ddc441f98b6e7f9ec3b9a4277b5bf91cad8d360564e2c46dfae3a4963e647b
4
+ data.tar.gz: 05c1fc9459671d0cad41b68c9f6e5e5003e006ba582a5fedf3b63aca379a85fa
5
5
  SHA512:
6
- metadata.gz: a67ac4027e5b1f8c5d70b4799f7cbd230c18c0b18a2100085c1876a97ece7b283b621a22981ac5f1e0d16e6c0f6383746d436080f57a2b1810a216230c20a74e
7
- data.tar.gz: baa04313709dd51cbe4269a9cf536559d88ea24d55409a0ba80dd9f1f1db9fa4b1f4ee03df9df57841bb5abe81250255bbb9b257d55fcd6e9f653b5dbc2479d2
6
+ metadata.gz: a6b4e23f4c7cbb1d4751e7aef27fabaa1e5ccb337276788489b08c031b0f3a9b9b3ac318328215579d78b2477ac95148af1dfa350a0635cb98959bb28c76b296
7
+ data.tar.gz: 8d836cbd60a8798408752818ec84b08165d27f9196645129683a1c15abd43288976575ad0e57c737c93e9169b9995a065c3d1bfea2a962da4b39f62d25f53a07
data/README.md CHANGED
@@ -14,7 +14,7 @@ Observes Active Record collections and notifies when a member loads an associati
14
14
  ```ruby
15
15
  require 'predictive_load'
16
16
  require 'predictive_load/active_record_collection_observation'
17
- ActiveRecord::Base.send(:include, PredictiveLoad::ActiveRecordCollectionObservation)
17
+ ActiveRecord::Base.include(PredictiveLoad::ActiveRecordCollectionObservation)
18
18
 
19
19
  require 'predictive_load/loader'
20
20
 
@@ -45,4 +45,3 @@ has_many :foos, predictive_load: false
45
45
 
46
46
  * Calling association#size will trigger an N+1 on SELECT COUNT(*). Work around by calling #length, loading all records.
47
47
  * Calling first / last will trigger an N+1.
48
- * Rails 4: unscoped will disable eager loading to circument a rails bug ... hopefully fixed in rails 5 https://github.com/rails/rails/pull/16531
@@ -45,18 +45,16 @@ module PredictiveLoad::ActiveRecordCollectionObservation
45
45
 
46
46
  # disable eager loading since includes + unscoped is broken on rails 4
47
47
  module UnscopedTracker
48
- if ActiveRecord::VERSION::MAJOR >= 4
49
- def unscoped
50
- if block_given?
51
- begin
52
- predictive_load_disabled << self
53
- super
54
- ensure
55
- predictive_load_disabled.pop
56
- end
57
- else
48
+ def unscoped
49
+ if block_given?
50
+ begin
51
+ predictive_load_disabled << self
58
52
  super
53
+ ensure
54
+ predictive_load_disabled.pop
59
55
  end
56
+ else
57
+ super
60
58
  end
61
59
  end
62
60
 
@@ -43,7 +43,7 @@ module PredictiveLoad
43
43
  return false if ActiveRecord::Base.predictive_load_disabled.include?(association.klass)
44
44
  return false if association.reflection.options[:predictive_load] == false
45
45
  return false if association.reflection.options[:conditions].respond_to?(:to_proc) # rails 3 conditions proc (we do not know if it uses instance methods)
46
- if ActiveRecord::VERSION::MAJOR > 3 && scope = association.reflection.scope
46
+ if scope = association.reflection.scope
47
47
  if scope.is_a?(Proc)
48
48
  # rails 4+ conditions block, if it uses a passed in object, we assume it is not preloadable
49
49
  return false if scope.arity.to_i > 0
@@ -56,21 +56,24 @@ module PredictiveLoad
56
56
  true
57
57
  end
58
58
 
59
- def preload(association_name)
60
- # https://github.com/rails/rails/blob/v4.2.10/activerecord/lib/active_record/associations/preloader.rb#L187 (similar to other Rails versions)
61
- # If the first record association is loaded, Preloader aborts.
62
- #
63
- # In a code like `comments.each { |c| c.user }, if the first comment user_id is nil,
64
- # when calling the method (`user`) ActiveRecord doesn't load the association, but marks it as loaded.
65
- # So when the second comment calls `user` (and user_id is not nil), @records.first will be the first
66
- # comment above (with thr association already loaded), which will be checked by Preloader and used to skip
67
- # any preloading.
68
- #
69
- # Fix is pretty simple, ignore any record with association already loaded.
70
- rs = records_with_association(association_name).reject { |r| r.association(association_name).loaded? }
71
- if ActiveRecord::VERSION::STRING <= "4.1.0"
72
- ActiveRecord::Associations::Preloader.new(rs, [ association_name ]).run
73
- else
59
+ # https://github.com/rails/rails/blob/v4.2.10/activerecord/lib/active_record/associations/preloader.rb#L187 (similar to other Rails versions)
60
+ # If the first record association is loaded, Preloader aborts.
61
+ #
62
+ # In a code like `comments.each { |c| c.user }, if the first comment user_id is nil,
63
+ # when calling the method (`user`) ActiveRecord doesn't load the association, but marks it as loaded.
64
+ # So when the second comment calls `user` (and user_id is not nil), @records.first will be the first
65
+ # comment above (with thr association already loaded), which will be checked by Preloader and used to skip
66
+ # any preloading.
67
+ #
68
+ # Fix is pretty simple, ignore any record with association already loaded.
69
+ if ActiveRecord::VERSION::MAJOR >= 7
70
+ def preload(association_name)
71
+ rs = records_with_association(association_name).reject { |r| r.association(association_name).loaded? }
72
+ ActiveRecord::Associations::Preloader.new(records: rs, associations: [association_name]).call
73
+ end
74
+ else
75
+ def preload(association_name)
76
+ rs = records_with_association(association_name).reject { |r| r.association(association_name).loaded? }
74
77
  ActiveRecord::Associations::Preloader.new.preload(rs, [ association_name ])
75
78
  end
76
79
  end
@@ -8,16 +8,14 @@ module PredictiveLoad
8
8
  def preload(association)
9
9
  grouped_records(association).each do |reflection, klasses|
10
10
  klasses.each do |klass, records|
11
- preload_scope = (ActiveRecord::VERSION::MAJOR == 3 ? options : self.preload_scope)
12
- preloader = preloader_for(reflection).new(klass, records, reflection, preload_scope)
11
+ preloader = preloader_for(reflection).new(klass, records, reflection, preload_scope)
13
12
 
14
13
  if preloader.respond_to?(:through_reflection)
15
14
  log("encountered :through association for #{association}. Requires loading records to generate query, so skipping for now.")
16
15
  next
17
16
  end
18
17
 
19
- scope = (ActiveRecord::VERSION::MAJOR == 3 ? preloader.scoped : preloader.scope)
20
- preload_sql = scope.where(collection_arel(preloader)).to_sql
18
+ preload_sql = preloader.scope.where(collection_arel(preloader)).to_sql
21
19
 
22
20
  log("would preload with: #{preload_sql.to_s}")
23
21
  klass.connection.explain(preload_sql).each_line do |line|
@@ -1,18 +1,13 @@
1
1
  module PredictiveLoad
2
-
3
- end
4
-
5
- klasses = [ActiveRecord::Associations::Builder::Association]
6
-
7
- if ActiveRecord::VERSION::MAJOR == 3
8
- # when belongs_to etc is loaded before us it already made a copy of valid_options
9
- klasses.concat ActiveRecord::Associations::Builder::Association.descendants
2
+ module Rails5AssociationOptions
3
+ def valid_options(options)
4
+ super + [:predictive_load]
5
+ end
6
+ end
10
7
  end
11
8
 
12
- klasses.each do |klass|
13
- if ActiveRecord::VERSION::MAJOR < 5
14
- klass.valid_options << :predictive_load
15
- else
16
- klass::VALID_OPTIONS << :predictive_load
17
- end
9
+ if ActiveRecord::VERSION::MAJOR >= 5
10
+ ActiveRecord::Associations::Builder::Association.singleton_class.prepend(PredictiveLoad::Rails5AssociationOptions)
11
+ else
12
+ ActiveRecord::Associations::Builder::Association.valid_options << :predictive_load
18
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: predictive_load
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Chapweske
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-13 00:00:00.000000000 Z
11
+ date: 2023-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.0
19
+ version: '6.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.3'
22
+ version: '7.1'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 4.2.0
29
+ version: '6.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.3'
32
+ version: '7.1'
33
33
  description: Predictive loader
34
34
  email:
35
35
  - eac@zendesk.com
@@ -47,7 +47,7 @@ homepage: https://github.com/zendesk/predictive_load
47
47
  licenses:
48
48
  - Apache License Version 2.0
49
49
  metadata: {}
50
- post_install_message:
50
+ post_install_message:
51
51
  rdoc_options: []
52
52
  require_paths:
53
53
  - lib
@@ -55,16 +55,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
55
  requirements:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
- version: '2.4'
58
+ version: '2.7'
59
59
  required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubyforge_project:
66
- rubygems_version: 2.7.6.2
67
- signing_key:
65
+ rubygems_version: 3.0.3.1
66
+ signing_key:
68
67
  specification_version: 4
69
68
  summary: ''
70
69
  test_files: []