Don't cache related actions in investments view

We've experienced some caching issues with this code for years. We've
fixed some of them in commits 9979b5399 and 3645c333a, but we're still
running into other issues. In order to really cache this section, we'd
need to cache:

* Whether or not the investment should show the aside and vote/support
  buttons (we could do it by caching its budget)
* Whether its budget is balloting or finished (we could do it by caching
  its budget)
* Whether the current user is following the investment
* Whether the `remove_investments_supports` feature is enabled
* Whether the `community` feature is enabled
* The value of the `org_name` setting
* The value of the `twitter_handle` setting

We weren't caching all these elements, meaning that (for instance), we
didn't display the button to vote when a budget moved into the voting
phase if we had already cached this section without the button.

And chances are the list is incomplete. So, instead of trying to take
into account every single possible factor that should make us expire the
cache, we're restricting the cache so it only affects the content of the
investment. This is similar to what we do in the investments index,
where we cache the content of the investment but we don't cache the
vote/support buttons.
This commit is contained in:
Javi Martín
2023-01-31 19:20:36 +01:00
parent 4debff754c
commit 02e8ffca36

View File

@@ -7,122 +7,118 @@
og_image_url: (investment.image.present? ? polymorphic_path(investment.image.variant(:thumb)) : nil) %> og_image_url: (investment.image.present? ? polymorphic_path(investment.image.variant(:thumb)) : nil) %>
<% end %> <% end %>
<% cache [locale_and_user_status(investment), <section class="budget-investment-show" id="<%= dom_id(investment) %>">
investment, <div class="row">
investment.author, <% cache [locale_and_user_status(investment),
Flag.flagged?(current_user, investment), investment,
investment.followed_by?(current_user), investment.author,
feature?(:remove_investments_supports), Flag.flagged?(current_user, investment)] do %>
current_user&.voted_for?(investment)] do %>
<section class="budget-investment-show" id="<%= dom_id(investment) %>">
<div class="row">
<div class="small-12 medium-9 column"> <div class="small-12 medium-9 column">
<%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %> <%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %>
<%= render "/budgets/investments/investment_detail", investment: investment %> <%= render "/budgets/investments/investment_detail", investment: investment %>
</div> </div>
<% end %>
<aside class="small-12 medium-3 column"> <aside class="small-12 medium-3 column">
<%= render "/budgets/investments/author_actions", investment: investment %> <%= render "/budgets/investments/author_actions", investment: investment %>
<% if investment.should_show_aside? %> <% if investment.should_show_aside? %>
<% if investment.should_show_votes? %> <% if investment.should_show_votes? %>
<div class="sidebar-divider"></div> <div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.supports") %></h2> <h2><%= t("budgets.investments.show.supports") %></h2>
<div class="text-center"> <div class="text-center">
<div id="<%= dom_id(investment) %>_votes"> <div id="<%= dom_id(investment) %>_votes">
<%= render Budgets::Investments::VotesComponent.new(investment) %> <%= render Budgets::Investments::VotesComponent.new(investment) %>
</div>
</div> </div>
<% elsif investment.should_show_vote_count? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.supports") %></h2>
<div class="text-center">
<span class="total-supports">
<strong>
<%= t("budgets.investments.investment.supports",
count: investment.total_votes) %>
</strong>
</span>
</div>
<% elsif investment.should_show_ballots? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.votes") %></h2>
<div class="text-center">
<div id="<%= dom_id(investment) %>_ballot">
<%= render "ballot",
investment: investment,
investment_ids: investment_ids,
ballot: ballot %>
</div>
</div>
<% end %>
<% end %>
<% if investment.unfeasible? && investment.valuation_finished? %>
<div class="callout warning">
<%= sanitize(t("budgets.investments.show.project_unfeasible")) %>
</div> </div>
<% elsif investment.winner? && @budget.finished? %> <% elsif investment.should_show_vote_count? %>
<div class="callout success"> <div class="sidebar-divider"></div>
<strong><%= t("budgets.investments.show.project_winner") %></strong> <h2><%= t("budgets.investments.show.supports") %></h2>
</div> <div class="text-center">
<% elsif investment.selected? %> <span class="total-supports">
<div class="callout success"> <strong>
<%= sanitize(t("budgets.investments.show.project_selected")) %> <%= t("budgets.investments.investment.supports",
</div> count: investment.total_votes) %>
<% elsif @budget.balloting_or_later? %> </strong>
<div class="callout warning">
<%= sanitize(t("budgets.investments.show.project_not_selected")) %>
</div>
<% else %>
<br>
<div class="float-right">
<span class="label-budget-investment float-left">
<%= t("budgets.investments.show.title") %>
</span> </span>
<span class="icon-budget"></span>
</div> </div>
<% end %> <% elsif investment.should_show_ballots? %>
<% if investment.should_show_price? %>
<div class="sidebar-divider"></div> <div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.price") %></h2> <h2><%= t("budgets.investments.show.votes") %></h2>
<div class="supports text-center"> <div class="text-center">
<p class="investment-project-amount"> <div id="<%= dom_id(investment) %>_ballot">
<%= investment.formatted_price %> <%= render "ballot",
</p> investment: investment,
</div> investment_ids: investment_ids,
<% if investment.should_show_price_explanation? %> ballot: ballot %>
<div class="text-center" data-magellan>
<%= link_to t("budgets.investments.show.see_price_explanation"),
"#price_explanation", class: "small" %>
</div> </div>
<% end %> </div>
<% end %> <% end %>
<% end %>
<%= render "shared/social_share", <% if investment.unfeasible? && investment.valuation_finished? %>
share_title: t("budgets.investments.show.share"), <div class="callout warning">
title: investment.title, <%= sanitize(t("budgets.investments.show.project_unfeasible")) %>
image_url: image_absolute_url(investment.image, :thumb), </div>
url: budget_investment_url(investment.budget, investment), <% elsif investment.winner? && @budget.finished? %>
description: t("budgets.investments.share.message", <div class="callout success">
title: investment.title, <strong><%= t("budgets.investments.show.project_winner") %></strong>
handle: setting["org_name"]), </div>
mobile: t("budgets.investments.share.message", <% elsif investment.selected? %>
title: investment.title, <div class="callout success">
handle: setting["twitter_handle"]) %> <%= sanitize(t("budgets.investments.show.project_selected")) %>
</div>
<% if current_user %> <% elsif @budget.balloting_or_later? %>
<div class="sidebar-divider"></div> <div class="callout warning">
<p class="sidebar-title"><%= t("shared.follow") %></p> <%= sanitize(t("budgets.investments.show.project_not_selected")) %>
</div>
<%= render "follows/follow_button", follow: find_or_build_follow(current_user, investment) %> <% else %>
<br>
<div class="float-right">
<span class="label-budget-investment float-left">
<%= t("budgets.investments.show.title") %>
</span>
<span class="icon-budget"></span>
</div>
<% end %>
<% if investment.should_show_price? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.price") %></h2>
<div class="supports text-center">
<p class="investment-project-amount">
<%= investment.formatted_price %>
</p>
</div>
<% if investment.should_show_price_explanation? %>
<div class="text-center" data-magellan>
<%= link_to t("budgets.investments.show.see_price_explanation"),
"#price_explanation", class: "small" %>
</div>
<% end %> <% end %>
<% end %>
<%= render "communities/access_button", community: investment.community %> <%= render "shared/social_share",
share_title: t("budgets.investments.show.share"),
title: investment.title,
image_url: image_absolute_url(investment.image, :thumb),
url: budget_investment_url(investment.budget, investment),
description: t("budgets.investments.share.message",
title: investment.title,
handle: setting["org_name"]),
mobile: t("budgets.investments.share.message",
title: investment.title,
handle: setting["twitter_handle"]) %>
</aside> <% if current_user %>
</div> <div class="sidebar-divider"></div>
</section> <p class="sidebar-title"><%= t("shared.follow") %></p>
<% end %>
<%= render "follows/follow_button", follow: find_or_build_follow(current_user, investment) %>
<% end %>
<%= render "communities/access_button", community: investment.community %>
</aside>
</div>
</section>