predictive_load 0.5.0 → 0.6.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: 54bffe32fe50393ce8bb75bd01ae397084d3c2924ea4dafa9bccddb860baedf3
4
- data.tar.gz: 1b37f4afd9874034fe0b7adc81317687d734cc51539665a5df005deefc0553c0
3
+ metadata.gz: f59d44d0c89dbf1ef633348451e1df43d6b059ddb50094549e2bc6a5f4843531
4
+ data.tar.gz: 75cd6c8518d8f200c13a8c52ed887b7e1a0d1e72aa02205305f7bc65d1b4b9ca
5
5
  SHA512:
6
- metadata.gz: 8af3089f4ab81c3470d2811a335d40e36bede5ca38c59cf739135ebf4fdb18d7181338d9065a7fff06ff436a54c73e4ad618c61a890d8ee610c935855542e1da
7
- data.tar.gz: de072a8eeaf0080dcf1bd2c1183b9b04f305c1206ed170737a6cbf97b62dee6945e876fb739b2495d715f9e1e373605383db35b13ed8ccb6b5a0f1bc71528e4c
6
+ metadata.gz: cfb8c2e28057981f773794139483805712c17faad421506c39d5309961b2be0c7d2b541c6afd4e0877f2e40703e3c036832651b6f569e57799d12ae0bd8ca20e
7
+ data.tar.gz: 49482a1ffcd183092f0f71242ab78fecca8b583a69aa8f90816173edcee4226f389061a36bccb27d455679132cb8dc6a756f6d3dc025293198213e5e7962cba4
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- [![Build Status](https://travis-ci.org/eac/predictive_load.png)](https://travis-ci.org/eac/predictive_load)
1
+ [![Build Status](https://github.com/zendesk/predictive_load/actions/workflows/actions.yml/badge.svg?branch=master)](https://github.com/zendesk/predictive_load/actions/workflows/actions.yml)
2
+
2
3
 
3
4
  predictive_load
4
5
  ===============
@@ -13,7 +14,7 @@ Observes Active Record collections and notifies when a member loads an associati
13
14
  ```ruby
14
15
  require 'predictive_load'
15
16
  require 'predictive_load/active_record_collection_observation'
16
- ActiveRecord::Base.send(:include, PredictiveLoad::ActiveRecordCollectionObservation)
17
+ ActiveRecord::Base.include(PredictiveLoad::ActiveRecordCollectionObservation)
17
18
 
18
19
  require 'predictive_load/loader'
19
20
 
@@ -9,8 +9,8 @@ module PredictiveLoad::ActiveRecordCollectionObservation
9
9
  end
10
10
  ActiveRecord::Base.include CollectionMember
11
11
  ActiveRecord::Base.extend UnscopedTracker
12
- ActiveRecord::Associations::Association.include AssociationNotification
13
- ActiveRecord::Associations::CollectionAssociation.include CollectionAssociationNotification
12
+ ActiveRecord::Associations::Association.prepend AssociationNotification
13
+ ActiveRecord::Associations::CollectionAssociation.prepend CollectionAssociationNotification
14
14
  end
15
15
 
16
16
  module Rails5RelationObservation
@@ -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
 
@@ -66,16 +64,10 @@ module PredictiveLoad::ActiveRecordCollectionObservation
66
64
  end
67
65
 
68
66
  module AssociationNotification
69
-
70
- def self.included(base)
71
- base.send(:alias_method, :load_target_without_notification, :load_target)
72
- base.send(:alias_method, :load_target, :load_target_with_notification)
73
- end
74
-
75
- def load_target_with_notification
67
+ def load_target
76
68
  notify_collection_observer if find_target?
77
69
 
78
- load_target_without_notification
70
+ super
79
71
  end
80
72
 
81
73
  protected
@@ -85,22 +77,14 @@ module PredictiveLoad::ActiveRecordCollectionObservation
85
77
  @owner.collection_observer.loading_association(@owner, self)
86
78
  end
87
79
  end
88
-
89
80
  end
90
81
 
91
82
  module CollectionAssociationNotification
92
-
93
- def self.included(base)
94
- base.send(:alias_method, :load_target_without_notification, :load_target)
95
- base.send(:alias_method, :load_target, :load_target_with_notification)
96
- end
97
-
98
- def load_target_with_notification
83
+ def load_target
99
84
  notify_collection_observer if find_target?
100
85
 
101
- load_target_without_notification
86
+ super
102
87
  end
103
-
104
88
  end
105
89
 
106
90
  end
@@ -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.0
4
+ version: 0.6.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: 2020-02-05 00:00:00.000000000 Z
11
+ date: 2022-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 4.2.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
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 4.2.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
@@ -62,9 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubyforge_project:
66
- rubygems_version: 2.7.6
67
- signing_key:
65
+ rubygems_version: 3.1.6
66
+ signing_key:
68
67
  specification_version: 4
69
68
  summary: ''
70
69
  test_files: []