File tree Expand file tree Collapse file tree 4 files changed +48
-1
lines changed Expand file tree Collapse file tree 4 files changed +48
-1
lines changed Original file line number Diff line number Diff line change
1
+ * Strict loading using ` :n_plus_one_only ` does not eagerly load child associations.
2
+
3
+ With this change, child associations are no longer eagerly loaded, to
4
+ match intended behavior and to prevent non-deterministic order issues caused
5
+ by calling methods like ` first ` or ` last ` . As ` first ` and ` last ` don't cause
6
+ an N+1 by themselves, calling child associations will no longer raise.
7
+ Fixes #49473 .
8
+
9
+ Before:
10
+
11
+ ``` ruby
12
+ person = Person .find(1 )
13
+ person.strict_loading!(mode: :n_plus_one_only )
14
+ person.posts.first
15
+ # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
16
+ person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
17
+ ```
18
+
19
+ After:
20
+
21
+ ` ` ` ruby
22
+ person = Person.find(1)
23
+ person.strict_loading!(mode: :n_plus_one_only)
24
+ person.posts.first # this is 1+1, not N+1
25
+ # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
26
+ person.posts.first.firm # no longer raises
27
+ ` ` `
28
+
29
+ * Reid Lynch *
30
+
1
31
* Allow ` Sqlite3Adapter` to use ` sqlite3` gem version ` 2.x`
2
32
3
33
* Mike Dalessio *
Original file line number Diff line number Diff line change @@ -303,7 +303,7 @@ def null_scope?
303
303
304
304
def find_from_target?
305
305
loaded? ||
306
- owner . strict_loading? ||
306
+ ( owner . strict_loading? && owner . strict_loading_all? ) ||
307
307
reflection . strict_loading? ||
308
308
owner . new_record? ||
309
309
target . any? { |record | record . new_record? || record . changed? }
Original file line number Diff line number Diff line change @@ -704,6 +704,11 @@ def strict_loading_n_plus_one_only?
704
704
@strict_loading_mode == :n_plus_one_only
705
705
end
706
706
707
+ # Returns +true+ if the record uses strict_loading with +:all+ mode enabled.
708
+ def strict_loading_all?
709
+ @strict_loading_mode == :all
710
+ end
711
+
707
712
# Marks this record as read only.
708
713
#
709
714
# customer = Customer.first
Original file line number Diff line number Diff line change @@ -86,6 +86,18 @@ def test_strict_loading_n_plus_one_only_mode_with_belongs_to
86
86
end
87
87
end
88
88
89
+ def test_strict_loading_n_plus_one_only_mode_does_not_eager_load_child_associations
90
+ developer = Developer . first
91
+ developer . strict_loading! ( mode : :n_plus_one_only )
92
+ developer . projects . first
93
+
94
+ assert_not_predicate developer . projects , :loaded?
95
+
96
+ assert_nothing_raised do
97
+ developer . projects . first . firm
98
+ end
99
+ end
100
+
89
101
def test_strict_loading
90
102
Developer . all . each { |d | assert_not d . strict_loading? }
91
103
Developer . strict_loading . each { |d | assert_predicate d , :strict_loading? }
You can’t perform that action at this time.
0 commit comments