Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document best practice around database queries in backend.md #11205

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

n1zyy
Copy link
Member

@n1zyy n1zyy commented Sep 5, 2024

🎫 Ticket

N/A

🛠 Summary of changes

This tries to capture the discussion in #11197 around documenting best practices for avoiding unnecessary database queries.

Relentless critique welcome on this.


```ruby
# Bad: potentially-unnecessary DB query
if mfa_user.two_factor_enabled? && !in_mfa_selection_flow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this example relies on specific knowledge of the MfaUser class which itself wraps an ActiveRecord object.

Maybe we could use some example illustrative names?

Suggested change
if mfa_user.two_factor_enabled? && !in_mfa_selection_flow
if model.association.count > 2 && !local_boolean

and then it might be clearer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debated this a bit, but you're probably right.

Part of what I wanted to try to convey is that two_factor_enabled? doesn't tell you it's going to do a database query; you need to pay some attention to what the methods are doing. But maybe this is too obtuse an example.

Comment on lines +169 to +174
In this example, the concern is specifically that the `two_factor_enabled?` method
issues a database query, fetching an association.

An alternative approach to consider when dealing with associations is to make use
of [eager loading](https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations),
which could allow fetching the associated records with a join in the same query.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I think it's pretty specific... maybe we could show an example of something we want to eager load:

# BAD
recent_users = User.last(10)
recent_emails = recent_users.flat_map { |u| u.email_addresses.email } # one EmailAddress query per user!

# GOOD
recent_users = User.includes(:email_addresses).last(10)
recent_emails = recent_users.flat_map { |u| u.email_addresses.email } # one EmailAddress query total!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice; an example of actually using it is a good idea.

This is another case where I probably would have used #collect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants