bulletmark_repairer 0.1.5 → 0.1.7

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: 3d44edbc5a6deb0c95e4e1ed79c2f2b1c7b283ff54e3f00d33bbf9a8b70f698e
4
- data.tar.gz: 5d3ba75ca53cd5e721f971894fc2f1001e1fd391f4daf44a53184ef861cb532b
3
+ metadata.gz: 39af4a769d591a28ab628d174b6224984bf3f87460e2ee4d782a5a16a3c04d87
4
+ data.tar.gz: 2b163d905540357085ef7d9436abc189d4cde357f95a5e7650b538b195bb95bc
5
5
  SHA512:
6
- metadata.gz: 617f5750639fe286efd6fa7d0d7bb40d0be0d258ef94600717ad98f2f46c6bfad966ea651bd5b0113f3ab9b0ff4d5749a5316bc7cca7c83c7dabc781d890ac20
7
- data.tar.gz: e6698f869f1c1f50b08332c6ec3134cfd32716325c5b2607e4a7247cf5bf807ed5f39f633822288d641246167b82e1f6b6e969d24b7cde322764204823fbea24
6
+ metadata.gz: c5a8331d8787887ff29e736d353978d6d86000d14713df1576f131c9a661aaf166421aa963bd4752a5d3d55f2ee642fdbfeac3e551defe126450cd6d4c5d1aa3
7
+ data.tar.gz: 9d9a6aa80d778ec59b86d4eea3123e732ab146b01dfaf46ef78a7d66ebb0e1923558a903eef36afd895fb97404b4650585ad7ee3b5cbc34e16b947d790952f7b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [0.1.7] - 2023-11-21
2
+
3
+ - Validate detected instance_variable is an ActiveRecord::Relation [ed650ae](https://github.com/makicamel/bulletmark_repairer/commit/ed650ae41b4389774cb1135031f077e953d2c5db) [86497bd](https://github.com/makicamel/bulletmark_repairer/commit/86497bd3cbb6daf1672cd18210e5842d0ecc084f)
4
+ - Add includes after methods returning AR on autocorrect [767e5e1](https://github.com/makicamel/bulletmark_repairer/commit/767e5e1389f84daa6efce4463a4979a100c16640)
5
+
6
+ ## [0.1.6] - 2023-11-09
7
+
8
+ Fix a bug when N+1 is caused not in the request (e.g. Sidekiq) [51f051e](https://github.com/makicamel/bulletmark_repairer/commit/51f051e608b84b7da96ac879a324ed438c14eeeb)
9
+
1
10
  ## [0.1.5] - 2023-10-27
2
11
 
3
12
  Be able to patch for nested associations require `includes` though child associations are already included [d1b7445](https://github.com/makicamel/bulletmark_repairer/commit/d1b7445556c20bc037beb6a013ac70531426a7ea)
@@ -33,6 +33,14 @@ class ControllerCorrector < Parser::TreeRewriter
33
33
  @patched ||= false
34
34
  end
35
35
 
36
+ def includes_token
37
+ @includes_token ||= ".includes(#{associations})"
38
+ end
39
+
40
+ def inserted?(parent_node)
41
+ parent_node.location.expression.source.include?(includes_token)
42
+ end
43
+
36
44
  def target_nodes
37
45
  @target_nodes ||= {}
38
46
  end
@@ -47,10 +55,8 @@ class ControllerCorrector < Parser::TreeRewriter
47
55
 
48
56
  type, identifier = node.to_sexp_array.take(2)
49
57
  if type == :ivasgn && identifier == instance_variable_name
50
- inserted = ".includes(#{associations})"
51
- unless node.location.expression.source.include?(inserted)
52
- insert_after node.children.last.location.expression, inserted
53
- @patched = true
58
+ node.children.each do |child_node|
59
+ execute_insert_includes(node: child_node, parent_node: node)
54
60
  end
55
61
  else
56
62
  node
@@ -67,6 +73,22 @@ class ControllerCorrector < Parser::TreeRewriter
67
73
  end
68
74
  end
69
75
 
76
+ def execute_insert_includes(node:, parent_node:)
77
+ return unless node.respond_to?(:children)
78
+ return if patched?
79
+
80
+ node.children.each do |child_node|
81
+ if child_node.is_a?(Symbol)
82
+ if BulletmarkRepairer::Thread.correctable_method?(child_node) && !inserted?(parent_node)
83
+ insert_after node.location.expression, includes_token
84
+ @patched = true
85
+ end
86
+ else
87
+ execute_insert_includes(node: child_node, parent_node: node)
88
+ end
89
+ end
90
+ end
91
+
70
92
  def action
71
93
  :__EMBEDDED_ACTION__
72
94
  end
@@ -82,7 +82,6 @@ module BulletmarkRepairer
82
82
  end
83
83
  view_file, view_yield_index = @stacktraces[view_file_index].scan(%r{\A(/[./\w]+):(\d+):in `[\w]+'\z}).flatten
84
84
  view_yield_index = view_yield_index.to_i
85
- # TODO: Compile views
86
85
  File.open(view_file) do |f|
87
86
  lines = f.readlines
88
87
  loop do
@@ -90,7 +89,8 @@ module BulletmarkRepairer
90
89
 
91
90
  view_yield_index -= 1
92
91
  line = lines[view_yield_index]
93
- @instance_variable_name = line&.scan(/\b?(@[\w]+)\b?/)&.flatten&.last
92
+ token = line&.scan(/\b?(@[\w]+)\b?/)&.flatten&.last
93
+ @instance_variable_name = token if BulletmarkRepairer::Thread.instance_variable_name?(token)
94
94
  end
95
95
  end
96
96
  @index = @instance_variable_name ? "#{view_file}:#{view_yield_index}" : nil
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulletmarkRepairer
4
+ module ActionView
5
+ module Base
6
+ def initialize(*args)
7
+ super(*args)
8
+ @_assigns.each do |ivname, value|
9
+ BulletmarkRepairer::Thread.memorize_instance_variable_name(name: ivname, value: value)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,17 +4,17 @@ module BulletmarkRepairer
4
4
  module ActiveRecord
5
5
  module QueryMethod
6
6
  def includes(*args)
7
- Thread.current[:bulletmark_repaier_loaded_associations][model.name][:includes].add(args)
7
+ BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :includes, args: args)
8
8
  super(args)
9
9
  end
10
10
 
11
11
  def eager_load(*args)
12
- Thread.current[:bulletmark_repaier_loaded_associations][model.name][:eager_load].add(args)
12
+ BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :eager_load, args: args)
13
13
  super(args)
14
14
  end
15
15
 
16
16
  def preload(*args)
17
- Thread.current[:bulletmark_repaier_loaded_associations][model.name][:preload].add(args)
17
+ BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :preload, args: args)
18
18
  super(args)
19
19
  end
20
20
  end
@@ -7,24 +7,28 @@ module BulletmarkRepairer
7
7
  end
8
8
 
9
9
  def call(env)
10
- Thread.current[:bulletmark_repaier_loaded_associations] = Hash.new do |hash, key|
11
- hash[key] = { includes: Set.new, eager_load: Set.new, preload: Set.new }
10
+ trace_point = TracePoint.trace(:return) do |tp|
11
+ BulletmarkRepairer::Thread.memorize_methods(
12
+ method_name: tp.method_id,
13
+ value: tp.return_value
14
+ )
12
15
  end
13
16
  @app.call(env)
14
17
  ensure
18
+ trace_point.disable
15
19
  begin
16
- if Thread.current[:bullet_notification_collector].notifications_present?
20
+ if ::Thread.current[:bullet_notification_collector].notifications_present?
17
21
  BulletmarkRepairer::Patcher.execute(
18
- notifications: Thread.current[:bullet_notification_collector],
22
+ notifications: ::Thread.current[:bullet_notification_collector],
19
23
  controller: env['action_dispatch.request.parameters']['controller'],
20
24
  action: env['action_dispatch.request.parameters']['action'],
21
- loaded_associations: Thread.current[:bulletmark_repaier_loaded_associations]
25
+ loaded_associations: BulletmarkRepairer::Thread.current(:loaded_associations)
22
26
  )
23
27
  end
24
28
  rescue StandardError => e
25
29
  raise e if BulletmarkRepairer.config.debug?
26
30
  end
27
- Thread.current[:bulletmark_repaier_loaded_associations].clear
31
+ BulletmarkRepairer::Thread.clear
28
32
  end
29
33
  end
30
34
  end
@@ -14,5 +14,9 @@ module BulletmarkRepairer
14
14
  require 'bulletmark_repairer/monkey_patches/active_record/query_method'
15
15
  ::ActiveRecord::Relation.prepend(BulletmarkRepairer::ActiveRecord::QueryMethod)
16
16
  end
17
+ ActiveSupport.on_load(:action_view) do
18
+ require 'bulletmark_repairer/monkey_patches/action_view/base'
19
+ ::ActionView::Base.prepend(BulletmarkRepairer::ActionView::Base)
20
+ end
17
21
  end
18
22
  end
@@ -13,6 +13,14 @@ class RetryCorrector < Parser::TreeRewriter
13
13
  @patched ||= false
14
14
  end
15
15
 
16
+ def includes_token
17
+ @includes_token ||= ".includes(#{associations})"
18
+ end
19
+
20
+ def inserted?(parent_node)
21
+ parent_node.location.expression.source.include?(includes_token)
22
+ end
23
+
16
24
  def insert_includes(node:)
17
25
  return if patched?
18
26
  return if !node.respond_to?(:children) || node.children.empty?
@@ -21,11 +29,25 @@ class RetryCorrector < Parser::TreeRewriter
21
29
  if node.type == :begin
22
30
  node.children.each { |child_node| insert_includes(node: child_node) }
23
31
  else
24
- inserted = ".includes(#{associations})"
25
- return if node.location.expression.source.include?(inserted)
32
+ node.children.each do |child_node|
33
+ execute_insert_includes(node: child_node, parent_node: node)
34
+ end
35
+ end
36
+ end
37
+
38
+ def execute_insert_includes(node:, parent_node:)
39
+ return unless node.respond_to?(:children)
40
+ return if patched?
26
41
 
27
- insert_after node.location.expression, ".includes(#{associations})"
28
- @patched = true
42
+ node.children.each do |child_node|
43
+ if child_node.is_a?(Symbol)
44
+ if BulletmarkRepairer::Thread.correctable_method?(child_node) && !inserted?(parent_node)
45
+ insert_after node.location.expression, includes_token
46
+ @patched = true
47
+ end
48
+ else
49
+ execute_insert_includes(node: child_node, parent_node: node)
50
+ end
29
51
  end
30
52
  end
31
53
 
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ module BulletmarkRepairer
6
+ class Thread
7
+ class << self
8
+ def current(key)
9
+ touch(key)
10
+ end
11
+
12
+ def memorize_associations(name:, method_type:, args:)
13
+ current(:loaded_associations)[name][method_type].add(args)
14
+ end
15
+
16
+ def memorize_instance_variable_name(name:, value:)
17
+ return unless value.is_a?(::ActiveRecord::Relation)
18
+
19
+ current(:loaded_instance_variables).add("@#{name}")
20
+ end
21
+
22
+ def instance_variable_name?(name)
23
+ current(:loaded_instance_variables).include?(name)
24
+ end
25
+
26
+ # TODO: Memorize methods with class
27
+ def memorize_methods(method_name:, value:)
28
+ return unless value.is_a?(::ActiveRecord::Associations::CollectionProxy) || value.is_a?(::ActiveRecord::Relation)
29
+
30
+ current(:loaded_methods).add(method_name)
31
+ end
32
+
33
+ def correctable_method?(method_name)
34
+ current(:loaded_methods).include?(method_name)
35
+ end
36
+
37
+ def clear
38
+ ::Thread.current[:bulletmark_repairer] = nil
39
+ end
40
+
41
+ private
42
+
43
+ def touch(key)
44
+ ::Thread.current[:bulletmark_repairer] ||= {}
45
+ case key
46
+ when :loaded_associations
47
+ ::Thread.current[:bulletmark_repairer][:loaded_associations] ||= Hash.new do |hash, key|
48
+ hash[key] = { includes: Set.new, eager_load: Set.new, preload: Set.new }
49
+ end
50
+ when :loaded_instance_variables
51
+ ::Thread.current[:bulletmark_repairer][:loaded_instance_variables] ||= Set.new
52
+ when :loaded_methods
53
+ ::Thread.current[:bulletmark_repairer][:loaded_methods] ||= Set.new
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BulletmarkRepairer
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.7'
5
5
  end
@@ -9,6 +9,7 @@ require 'bulletmark_repairer/corrector_builder'
9
9
  require 'bulletmark_repairer/loaded_associations'
10
10
  require 'bulletmark_repairer/markers'
11
11
  require 'bulletmark_repairer/patcher'
12
+ require 'bulletmark_repairer/thread'
12
13
 
13
14
  module BulletmarkRepairer
14
15
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bulletmark_repairer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - makicamel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-27 00:00:00.000000000 Z
11
+ date: 2023-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -90,11 +90,13 @@ files:
90
90
  - lib/bulletmark_repairer/corrector_builder.rb
91
91
  - lib/bulletmark_repairer/loaded_associations.rb
92
92
  - lib/bulletmark_repairer/markers.rb
93
+ - lib/bulletmark_repairer/monkey_patches/action_view/base.rb
93
94
  - lib/bulletmark_repairer/monkey_patches/active_record/query_method.rb
94
95
  - lib/bulletmark_repairer/patcher.rb
95
96
  - lib/bulletmark_repairer/rack.rb
96
97
  - lib/bulletmark_repairer/railtie.rb
97
98
  - lib/bulletmark_repairer/retry_corrector.rb
99
+ - lib/bulletmark_repairer/thread.rb
98
100
  - lib/bulletmark_repairer/version.rb
99
101
  - sig/bulletmark_repairer.rbs
100
102
  homepage: https://github.com/makicamel/bulletmark_repairer