eager_eye 1.2.12 → 1.2.13

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: d6d4e056fa0d51ee629c031675f0e1b2ae2de62a1ebde0161f9d8d3d6f860f90
4
- data.tar.gz: e8c8239cc5017c68b1d4b91279a212086b1741493327eea0bc0059622de83116
3
+ metadata.gz: c9b4195fa833057ee04ef87d148e78de8463fdbca97e234ba9d5b08ecaab9afc
4
+ data.tar.gz: f5c45a109aba0f563866669c4b6a32ce0823990fe5de467d65f6baea8d405197
5
5
  SHA512:
6
- metadata.gz: deb89e2a0cedaa0d0fc41874a124725c1403634a105f157e66c52b6f80c63d02bf120bd4aa43765b452951b648972ad442deea3ca970d5355c4f79c34a3b5def
7
- data.tar.gz: dcdbff4d567c605f0525c56d1e205e33e9383098eb30428bd336913917367afa00ff3b3bae893ba3b961d7bcb069528b28d44dd4a9613904aff29344bdfd8865
6
+ metadata.gz: 8312903e2476381ad7d9fe8a5a22feb74eb97937c5d488efc96448df9b0f5973f9d612c35cccd5235900e2eb25011694c862bb1a45a5bdeb70b2a8e17be155e2
7
+ data.tar.gz: cc7b4336007a72b0d4131b311a2897d4dae9cf0b4ba18ceb4826f25931875f418067bd5a16e6d1fec472cbb29abd7d1f2d2f0b58cc943b871fdea4e9991fa623
data/README.md CHANGED
@@ -57,7 +57,8 @@
57
57
 
58
58
  🔧 **Developer-friendly:**
59
59
  - Inline suppression (like RuboCop)
60
- - Auto-fix support (experimental)
60
+ - Auto-fix support (3 fixers: PluckToSelect, CountToSize, AddIncludes)
61
+ - `.jbuilder` file support (`json.array!` iteration detection)
61
62
  - JSON/Console output formats
62
63
  - RSpec integration
63
64
 
@@ -524,6 +525,8 @@ eager_eye --fix --force
524
525
  | Issue | Fix |
525
526
  |-------|-----|
526
527
  | `.pluck(:id)` inline | → `.select(:id)` |
528
+ | `.count` in iteration | → `.size` |
529
+ | Missing `includes` before loop | → `.includes(:assoc)` inserted |
527
530
 
528
531
  ### Example
529
532
 
@@ -535,6 +538,15 @@ app/services/user_service.rb:
535
538
  - Post.where(user_id: User.active.pluck(:id))
536
539
  + Post.where(user_id: User.active.select(:id))
537
540
 
541
+ app/controllers/posts_controller.rb:
542
+ Line 8:
543
+ - user.posts.count
544
+ + user.posts.size
545
+
546
+ Line 5:
547
+ - @posts.each do |post|
548
+ + @posts.includes(:author).each do |post|
549
+
538
550
  $ eager_eye --fix
539
551
  app/services/user_service.rb:12
540
552
  - Post.where(user_id: User.active.pluck(:id))
@@ -739,7 +751,7 @@ EagerEye uses static analysis, which means:
739
751
  - **No runtime context** - Cannot know if associations are already eager loaded elsewhere
740
752
  - **Heuristic-based** - Uses naming conventions to identify associations (may have false positives)
741
753
  - **Ruby code only** - Does not analyze SQL queries or ActiveRecord internals
742
- - **Cross-file scope** - Cross-file analysis is limited to model-defined methods; controller-to-view or service-to-service patterns are not yet tracked
754
+ - **Cross-file scope** - Cross-file analysis covers model-defined query methods; controller-to-view or service-to-service patterns are not yet tracked
743
755
 
744
756
  For best results, use EagerEye alongside runtime tools like Bullet for comprehensive N+1 detection.
745
757
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ module Fixers
5
+ class AddIncludes < Base
6
+ ITERATION_METHODS_RE = %w[
7
+ each map collect select find_all reject filter filter_map
8
+ flat_map find_each find_in_batches in_batches
9
+ ].join("|")
10
+ ITERATION_PATTERN = /\.(#{ITERATION_METHODS_RE})\b/
11
+
12
+ def fixable?
13
+ issue.detector == :loop_association &&
14
+ !association_name.nil? &&
15
+ !iteration_line_index.nil?
16
+ end
17
+
18
+ def diff
19
+ return nil unless fixable?
20
+
21
+ idx = iteration_line_index
22
+ original_line = @source_lines[idx]
23
+ fixed_line = insert_includes(original_line)
24
+ return nil if original_line == fixed_line
25
+
26
+ {
27
+ file: issue.file_path,
28
+ line: idx + 1,
29
+ original: original_line.chomp,
30
+ fixed: fixed_line.chomp
31
+ }
32
+ end
33
+
34
+ protected
35
+
36
+ def fixed_content
37
+ raise NotImplementedError
38
+ end
39
+
40
+ private
41
+
42
+ def association_name
43
+ return nil unless issue.suggestion
44
+
45
+ match = issue.suggestion.match(/includes\(:(\w+)\)/)
46
+ match && match[1]
47
+ end
48
+
49
+ def iteration_line_index
50
+ start = issue.line_number - 2
51
+ start.downto([start - 10, 0].max) do |i|
52
+ return i if @source_lines[i]&.match?(ITERATION_PATTERN)
53
+ end
54
+ nil
55
+ end
56
+
57
+ def insert_includes(line)
58
+ line.sub(ITERATION_PATTERN, ".includes(:#{association_name})\\0")
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ module Fixers
5
+ class CountToSize < Base
6
+ def fixable?
7
+ issue.detector == :count_in_iteration &&
8
+ single_line_count?
9
+ end
10
+
11
+ protected
12
+
13
+ def fixed_content
14
+ line_content.sub(/\.count\b/, ".size")
15
+ end
16
+
17
+ private
18
+
19
+ def single_line_count?
20
+ line_content&.match?(/\.count\b/)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EagerEye
4
- VERSION = "1.2.12"
4
+ VERSION = "1.2.13"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eager_eye
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.12
4
+ version: 1.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamzagedikkaya
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-03-19 00:00:00.000000000 Z
11
+ date: 2026-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast
@@ -80,7 +80,9 @@ files:
80
80
  - lib/eager_eye/detectors/serializer_nesting.rb
81
81
  - lib/eager_eye/detectors/validation_n_plus_one.rb
82
82
  - lib/eager_eye/fixer_registry.rb
83
+ - lib/eager_eye/fixers/add_includes.rb
83
84
  - lib/eager_eye/fixers/base.rb
85
+ - lib/eager_eye/fixers/count_to_size.rb
84
86
  - lib/eager_eye/fixers/pluck_to_select.rb
85
87
  - lib/eager_eye/generators/install_generator.rb
86
88
  - lib/eager_eye/issue.rb