sdubois
(Sébastien Dubois)
February 13, 2021, 12:36pm
11
@Lexingtonn the specific issue I had (there might be others) was that find_by doesn’t care about eager loading. A fix was proposed by Alex in the thread I linked:
first_or_initialize calls first , which is compatible with includes (since it checks for loaded? .
By contrast, find_or_initialize_by calls find_by which always runs a query .
I agree. I think this a bug, I’ll have a go at a fix.
The original strict loading scope just covered things you can cover with includes, preload, etc. That’s probably why this isn’t included.
rails:main
← ghiculescu:strict-loading-find-by
opened 11:17PM - 12 Feb 21 UTC
In https://discuss.rubyonrails.org/t/how-to-enforce-strict-loading-of-records it… was mentioned that strict loading violations aren't triggered when you call `find_by` on a relation. This is surprising if you don't that `find_by` always executes a query, even if you use `includes`/`preload`.
To make things less surprising, this PR expands strict loading to also work when calling `find_by`. This will happen even if you use `includes`, since a query would still execute. So, any of these will now raise:
```ruby
developer = Developer.first
Developer.strict_loading_by_default = true
Developer.first.audit_logs.find_by(criteria: "anything")
developer.audit_logs.find_by(criteria: "anything")
# bad despite `includes` because `find_by` always queries
Developer.includes(:audit_logs).first.audit_logs.find_by(criteria: "anything")
Developer.strict_loading_by_default = false
Developer.strict_loading.first.audit_logs.find_by(criteria: "anything")
```
To avoid the errors, either avoid using `find_by`, or don't enable strict loading on the relevant query. eg. these are fine:
```ruby
Developer.strict_loading_by_default = false
# fine because no strict loading enabled
Developer.first.audit_logs.find_by(criteria: "anything")
```
```ruby
Developer.strict_loading_by_default = true
# fine because no n+1
Developer.includes(:audit_logs).first.audit_logs.to_a.find {|a| a.criteria == "anything"}
```
1 Like