Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ This is a Rails 8.1.0 application built with:

For detailed setup and development instructions, please see our [CONTRIBUTING.md](CONTRIBUTING.md) guide.

## Production Maintenance

### Featured workshops not showing on the home page

Featured workshop IDs are cached for up to 1 year. The cache auto-invalidates when a workshop's `featured`, `publicly_featured`, or `published` flags change, but stale data can persist if the invalidation races with the save transaction. To force a refresh, visit:

```
/?bust_cache=true
```

This clears and repopulates the cache for all users.

## Orphaned Reports

When users are deleted from the system, their reports are automatically assigned to a special
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/home/workshops_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ module Home
class WorkshopsController < ApplicationController
def index
authorize! :home
if params[:bust_cache] == "true" && current_user&.super_user?
Rails.cache.delete("featured_and_publicly_featured_workshop_ids")
end

ids = Rails.cache.fetch("featured_and_publicly_featured_workshop_ids", expires_in: 1.year) do
Workshop.featured_or_publicly_featured.pluck(:id)
end

base_scope = Workshop.includes(:windows_type, primary_asset: { file_attachment: :blob }, gallery_assets: { file_attachment: :blob })
.where(id: ids)
.where(id: ids)

@workshops = authorized_scope(base_scope, with: HomePolicy).decorate
@workshops = @workshops.sort { |x, y| Date.parse(y.date) <=> Date.parse(x.date) }
Expand Down
2 changes: 1 addition & 1 deletion app/views/home/_workshops.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
title: title,
subtitle: "Spotlights from our curriculum" %>

<%= turbo_frame_tag "home_workshops", src: home_workshops_path do %>
<%= turbo_frame_tag "home_workshops", src: home_workshops_path(bust_cache: params[:bust_cache].presence) do %>
<%= render "workshops_cards_skeleton" %>
<% end %>
</div>
Expand Down
53 changes: 53 additions & 0 deletions spec/requests/home/workshops_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require "rails_helper"

RSpec.describe "/home/workshops", type: :request do
let(:user) { create(:user) }
let!(:windows_type) { create(:windows_type) }

before { sign_in user }

describe "GET /home/workshops" do
it "returns featured workshops" do
workshop = create(:workshop, :published, featured: true, windows_type: windows_type)

get home_workshops_path

expect(response).to have_http_status(:ok)
expect(response.body).to include(workshop.title)
end

it "does not return unfeatured workshops" do
create(:workshop, :published, featured: false, windows_type: windows_type)

get home_workshops_path

expect(response).to have_http_status(:ok)
expect(response.body).to include("No workshops available right now.")
end

context "with bust_cache=true" do
let(:admin) { create(:user, :admin) }

before do
# Prime the cache with no featured workshops
get home_workshops_path
# Feature a workshop after the cache is set
create(:workshop, :published, featured: true, windows_type: windows_type)
end

it "clears the cache for admins" do
sign_in admin

get home_workshops_path, params: { bust_cache: "true" }

expect(response.body).not_to include("No workshops available right now.")
end

it "does not clear the cache for non-admins" do
get home_workshops_path, params: { bust_cache: "true" }

expect(response.body).to include("No workshops available right now.")
end
end
end
end
Loading