predictive_load 0.5.1 → 0.7.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
  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: []