diff --git a/db/migrate/20260520193213_add_subjects_count_to_collections.rb b/db/migrate/20260520193213_add_subjects_count_to_collections.rb new file mode 100644 index 000000000..e827bdf90 --- /dev/null +++ b/db/migrate/20260520193213_add_subjects_count_to_collections.rb @@ -0,0 +1,8 @@ +class AddSubjectsCountToCollections < ActiveRecord::Migration[7.2] + disable_ddl_transaction! + + def change + add_column :collections, :subjects_count, :integer, default: 0 + add_index :collections, :subjects_count, algorithm: :concurrently + end +end diff --git a/db/structure.sql b/db/structure.sql index ade9f7e0f..217a2bcf2 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -234,7 +234,8 @@ CREATE TABLE public.collections ( slug character varying DEFAULT ''::character varying, favorite boolean DEFAULT false NOT NULL, default_subject_id integer, - description text DEFAULT ''::text + description text DEFAULT ''::text, + subjects_count integer DEFAULT 0 ); @@ -2823,6 +2824,13 @@ CREATE INDEX index_collections_on_private ON public.collections USING btree (pri CREATE INDEX index_collections_on_slug ON public.collections USING btree (slug); +-- +-- Name: index_collections_on_subjects_count; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_collections_on_subjects_count ON public.collections USING btree (subjects_count); + + -- -- Name: index_collections_projects_on_collection_id; Type: INDEX; Schema: public; Owner: - -- @@ -4240,6 +4248,7 @@ ALTER TABLE ONLY public.users SET search_path TO "$user", public; INSERT INTO "schema_migrations" (version) VALUES +('20260520193213'), ('20260323120200'), ('20260323120100'), ('20260323120000'), diff --git a/lib/tasks/collections.rake b/lib/tasks/collections.rake new file mode 100644 index 000000000..dbc10a1b7 --- /dev/null +++ b/lib/tasks/collections.rake @@ -0,0 +1,22 @@ +namespace :collections do + desc 'Backfill subjects_count on collections' + task backfill_subjects_count: :environment do + Collection.in_batches(of: 1_000) do |batch| + collection_ids = batch.pluck(:id) + + counts = CollectionSubject + .where(collection_id: collection_ids) + .group(:collection_id) + .count + + collections_to_update = collection_ids.map do |id| + [id, counts[id] || 0] + end + + collections_to_update.each do |id, count| + Collection.where(id: id) + .update_all(subjects_count: count) + end + end + end +end