Remove investment supports query optimizations

In the previous commit I mentioned:

> If I'm right, the `investment_votes` instance variable only exists to
> avoid several database queries to get whether the current user has
> supported each of the investments.
>
> However, that doesn't make much sense when only one investment is
> shown.

Now let's discuss the case when there are several investments, like in
the investments index:

* There are 10 investments per page by default
* Each query takes less than a millisecond
* We still make a query per investment to check whether the current user
  voted in a different group
* AFAIK, there have been no performance tests showing these
  optimizations make the request to the investments index significantly
  faster
* These optimizations make the code way more complex than it is without
  them

Considering all these points, I'm removing the optimizations. I'm fine
with adding `includes` calls to preload records and avoid N+1 queries
even if there are no performance tests showing they make the application
faster because the effect on the code complexity is negligible. But
that's not the case here.

Note we're using `defined?` instead of the `||=` operator because the
`||=` operator will not serve its purpose when the result of the
operation returns `false`.
This commit is contained in:
Javi Martín
2021-06-13 04:23:43 +02:00
parent 5fab843184
commit 0214184b2d
8 changed files with 5 additions and 29 deletions

View File

@@ -1,11 +1,10 @@
class Budgets::Investments::VotesComponent < ApplicationComponent
attr_reader :investment, :investment_votes
attr_reader :investment
delegate :namespace, :current_user, :voted_for?, :image_absolute_url,
:link_to_verify_account, :link_to_signin, :link_to_signup, to: :helpers
def initialize(investment, investment_votes: nil)
def initialize(investment)
@investment = investment
@investment_votes = investment_votes
end
def vote_path
@@ -28,11 +27,8 @@ class Budgets::Investments::VotesComponent < ApplicationComponent
end
def user_voted_for?
@user_voted_for ||= if investment_votes
voted_for?(investment_votes, investment)
else
current_user&.voted_for?(investment)
end
@user_voted_for = current_user&.voted_for?(investment) unless defined?(@user_voted_for)
@user_voted_for
end
def display_support_alert?

View File

@@ -47,7 +47,6 @@ module Budgets
@investment_ids = @investments.pluck(:id)
@investments_map_coordinates = MapLocation.where(investment: investments).map(&:json_data)
load_investment_votes(@investments)
@tag_cloud = tag_cloud
@remote_translations = detect_remote_translations(@investments)
end
@@ -128,10 +127,6 @@ module Budgets
"budget_investment"
end
def load_investment_votes(investments)
@investment_votes = current_user ? current_user.budget_investment_votes(investments) : {}
end
def investment_params
attributes = [:heading_id, :tag_list, :organization_name, :location,
:terms_of_service, :related_sdg_list,

View File

@@ -15,7 +15,6 @@ class Management::Budgets::InvestmentsController < Management::BaseController
def index
@investments = @investments.apply_filters_and_search(@budget, params).page(params[:page])
load_investment_votes(@investments)
end
def new
@@ -49,15 +48,10 @@ class Management::Budgets::InvestmentsController < Management::BaseController
def print
@investments = @investments.apply_filters_and_search(@budget, params).order(cached_votes_up: :desc).for_render.limit(15)
load_investment_votes(@investments)
end
private
def load_investment_votes(investments)
@investment_votes = managed_user ? managed_user.budget_investment_votes(investments) : {}
end
def investment_params
attributes = [:external_url, :heading_id, :tag_list, :organization_name, :location,
image_attributes: image_attributes,

View File

@@ -161,11 +161,6 @@ class User < ApplicationRecord
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
end
def budget_investment_votes(budget_investments)
voted = votes.for_budget_investments(budget_investments)
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
end
def comment_flags(comments)
comment_flags = flags.for_comments(comments)
comment_flags.each_with_object({}) { |f, h| h[f.flaggable_id] = true }

View File

@@ -38,8 +38,7 @@
<div id="<%= dom_id(investment) %>_votes"
class="small-12 medium-3 column text-center"
<%= "data-equalizer-watch" if feature?(:allow_images) && investment.image.present? %>>
<%= render Budgets::Investments::VotesComponent.new(investment,
investment_votes: investment_votes) %>
<%= render Budgets::Investments::VotesComponent.new(investment) %>
</div>
<% elsif investment.should_show_vote_count? %>
<div id="<%= dom_id(investment) %>_votes"

View File

@@ -78,7 +78,6 @@
<%= render "/budgets/investments/investment",
investment: investment,
investment_ids: @investment_ids,
investment_votes: @investment_votes,
ballot: @ballot %>
<% end %>
<% else %>

View File

@@ -21,7 +21,6 @@
<%= render "/budgets/investments/investment",
investment: investment,
investment_ids: @investment_ids,
investment_votes: @investment_votes,
ballot: @ballot %>
<% end %>

View File

@@ -26,7 +26,6 @@
<%= render "/budgets/investments/investment",
investment: investment,
investment_ids: @investment_ids,
investment_votes: @investment_votes,
ballot: @ballot %>
<% end %>