Skip to content

Commit 5496af8

Browse files
committed
fix: solve N+1 queries issues
1 parent 6c35a4b commit 5496af8

3 files changed

Lines changed: 81 additions & 27 deletions

File tree

app/controllers/api/v1/base_controller.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,18 @@ def render_forbidden_policy(exception)
162162
end
163163

164164
def render_internal_error(exception)
165-
Rails.logger.error("Internal error: #{exception.class} - #{exception.message}")
166-
Rails.logger.error(exception.backtrace.join("\n")) if exception.backtrace
165+
# Log detailed error information
166+
Rails.logger.error("=" * 80)
167+
Rails.logger.error("INTERNAL ERROR: #{exception.class}")
168+
Rails.logger.error("Message: #{exception.message}")
169+
Rails.logger.error("Controller: #{controller_name}##{action_name}")
170+
Rails.logger.error("User: #{current_user&.email || 'anonymous'}")
171+
Rails.logger.error("Organization: #{current_organization&.name || 'N/A'}")
172+
Rails.logger.error("Request: #{request.method} #{request.path}")
173+
Rails.logger.error("Params: #{params.except(:controller, :action).inspect}")
174+
Rails.logger.error("Backtrace:")
175+
Rails.logger.error(exception.backtrace&.first(10)&.join("\n"))
176+
Rails.logger.error("=" * 80)
167177

168178
# In development, show detailed error; in production, be vague for security
169179
if Rails.env.development?

app/serializers/organization_serializer.rb

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,37 +56,75 @@ class OrganizationSerializer < Blueprinter::Base
5656
end
5757

5858
field :statistics do |org|
59-
{
60-
total_players: org.cached_players_count,
61-
active_players: org.players.where(deleted_at: nil, status: 'active').count,
62-
total_matches: org.matches.count,
63-
recent_matches: org.cached_monthly_matches_count,
64-
total_users: org.users.count
65-
}
59+
begin
60+
{
61+
total_players: org.cached_players_count,
62+
active_players: org.players.where(deleted_at: nil, status: 'active').count,
63+
total_matches: org.matches.count,
64+
recent_matches: org.cached_monthly_matches_count,
65+
total_users: org.users.count
66+
}
67+
rescue => e
68+
Rails.logger.error("OrganizationSerializer statistics error: #{e.class} - #{e.message}")
69+
Rails.logger.error(e.backtrace&.first(5)&.join("\n"))
70+
{
71+
total_players: 0,
72+
active_players: 0,
73+
total_matches: 0,
74+
recent_matches: 0,
75+
total_users: 0
76+
}
77+
end
6678
end
6779

6880
# Tier features and capabilities
6981
field :features do |org|
70-
{
71-
can_access_scrims: org.can_access_scrims?,
72-
can_access_competitive_data: org.can_access_competitive_data?,
73-
can_access_predictive_analytics: org.can_access_predictive_analytics?,
74-
available_features: org.available_features,
75-
available_data_sources: org.available_data_sources,
76-
available_analytics: org.available_analytics
77-
}
82+
begin
83+
{
84+
can_access_scrims: org.can_access_scrims?,
85+
can_access_competitive_data: org.can_access_competitive_data?,
86+
can_access_predictive_analytics: org.can_access_predictive_analytics?,
87+
available_features: org.available_features,
88+
available_data_sources: org.available_data_sources,
89+
available_analytics: org.available_analytics
90+
}
91+
rescue => e
92+
Rails.logger.error("OrganizationSerializer features error: #{e.class} - #{e.message}")
93+
Rails.logger.error(e.backtrace&.first(5)&.join("\n"))
94+
{
95+
can_access_scrims: false,
96+
can_access_competitive_data: false,
97+
can_access_predictive_analytics: false,
98+
available_features: [],
99+
available_data_sources: [],
100+
available_analytics: []
101+
}
102+
end
78103
end
79104

80105
field :limits do |org|
81-
# Chamar tier_limits uma única vez e retornar apenas os campos necessários
82-
limits = org.tier_limits
83-
{
84-
max_players: limits[:max_players],
85-
max_matches_per_month: limits[:max_matches_per_month],
86-
current_players: limits[:current_players],
87-
current_monthly_matches: limits[:current_monthly_matches],
88-
players_remaining: limits[:players_remaining],
89-
matches_remaining: limits[:matches_remaining]
90-
}
106+
begin
107+
# Chamar tier_limits uma única vez e retornar apenas os campos necessários
108+
limits = org.tier_limits
109+
{
110+
max_players: limits[:max_players],
111+
max_matches_per_month: limits[:max_matches_per_month],
112+
current_players: limits[:current_players],
113+
current_monthly_matches: limits[:current_monthly_matches],
114+
players_remaining: limits[:players_remaining],
115+
matches_remaining: limits[:matches_remaining]
116+
}
117+
rescue => e
118+
Rails.logger.error("OrganizationSerializer limits error: #{e.class} - #{e.message}")
119+
Rails.logger.error(e.backtrace&.first(5)&.join("\n"))
120+
{
121+
max_players: 0,
122+
max_matches_per_month: 0,
123+
current_players: 0,
124+
current_monthly_matches: 0,
125+
players_remaining: 0,
126+
matches_remaining: 0
127+
}
128+
end
91129
end
92130
end

config/database.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ default: &default
2020
# For details on connection pooling, see Rails configuration guide
2121
# https://guides.rubyonrails.org/configuring.html#database-pooling
2222
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
23+
# Connection timeout settings
24+
connect_timeout: 5
25+
checkout_timeout: 5
26+
# Statement timeout (prevents long-running queries)
27+
variables:
28+
statement_timeout: 10000 # 10 seconds
2329

2430
development:
2531
<<: *default

0 commit comments

Comments
 (0)