Add counter caches

pull/1/head
rebuilt 4 years ago
parent c03615cb43
commit a6ad132c81

@ -1,21 +1,19 @@
import { Controller } from "@hotwired/stimulus" import { Controller } from "@hotwired/stimulus";
// Connects to data-controller="analyze" // Connects to data-controller="analyze"
export default class extends Controller { export default class extends Controller {
connect() { } connect() {}
refresh(event) { refresh(event) {
let location = event.target.value+ "&academic_years="; let location = event.target.value;
let year_checkboxes = document.getElementsByName("year-checkbox"); let year_checkboxes = [...document.getElementsByName("year-checkbox")];
let selected_years = [];
let ending = ""; let selected_years = year_checkboxes
year_checkboxes.forEach((item)=>{ .filter((item) => {
if(item.checked) { return item.checked;
selected_years.push(item.id) })
} .map((item) => {
}) return item.id;
});
console.log(location) window.location = location + "&academic_years=" + selected_years.join(",");
window.location = location + selected_years.join(",")
} }
} }

@ -1,5 +1,5 @@
class Measure < ActiveRecord::Base class Measure < ActiveRecord::Base
belongs_to :subcategory belongs_to :subcategory, counter_cache: true
has_one :category, through: :subcategory has_one :category, through: :subcategory
has_many :scales has_many :scales
has_many :admin_data_items, through: :scales has_many :admin_data_items, through: :scales
@ -203,14 +203,23 @@ class Measure < ActiveRecord::Base
end end
def sufficient_student_data?(school:, academic_year:) def sufficient_student_data?(school:, academic_year:)
return false unless includes_student_survey_items? return @sufficient_student_data ||= false unless includes_student_survey_items?
return @sufficient_student_data ||= false if student_survey_items_by_survey_type(school:,
academic_year:).all? do |survey_item|
survey_item.survey_item_responses.where(school:,
academic_year:).none?
end
@sufficient_student_data ||= subcategory.response_rate(school:, academic_year:).meets_student_threshold @sufficient_student_data ||= subcategory.response_rate(school:, academic_year:).meets_student_threshold?
end end
def sufficient_teacher_data?(school:, academic_year:) def sufficient_teacher_data?(school:, academic_year:)
return false unless includes_teacher_survey_items? return @sufficient_teacher_data ||= false unless includes_teacher_survey_items?
return @sufficient_teacher_data ||= false if teacher_survey_items.all? do |survey_item|
survey_item.survey_item_responses.where(school:,
academic_year:).none?
end
@sufficient_teacher_data ||= subcategory.response_rate(school:, academic_year:).meets_teacher_threshold @sufficient_teacher_data ||= subcategory.response_rate(school:, academic_year:).meets_teacher_threshold?
end end
end end

@ -1,5 +1,5 @@
class Scale < ApplicationRecord class Scale < ApplicationRecord
belongs_to :measure belongs_to :measure, counter_cache: true
has_many :survey_items has_many :survey_items
has_many :survey_item_responses, through: :survey_items has_many :survey_item_responses, through: :survey_items
has_many :admin_data_items has_many :admin_data_items

@ -1,5 +1,5 @@
class Subcategory < ActiveRecord::Base class Subcategory < ActiveRecord::Base
belongs_to :category belongs_to :category, counter_cache: true
has_many :measures has_many :measures

@ -1,5 +1,5 @@
class SurveyItem < ActiveRecord::Base class SurveyItem < ActiveRecord::Base
belongs_to :scale belongs_to :scale, counter_cache: true
has_one :measure, through: :scale has_one :measure, through: :scale
has_one :subcategory, through: :measure has_one :subcategory, through: :measure

@ -4,7 +4,7 @@ class SurveyItemResponse < ActiveRecord::Base
belongs_to :academic_year belongs_to :academic_year
belongs_to :school belongs_to :school
belongs_to :survey_item belongs_to :survey_item, counter_cache: true
has_one :measure, through: :survey_item has_one :measure, through: :survey_item
scope :exclude_boston, lambda { scope :exclude_boston, lambda {

@ -1,5 +1,5 @@
class ResponseRateLoader class ResponseRateLoader
def self.refresh def self.reset
schools = School.all schools = School.all
academic_years = AcademicYear.all academic_years = AcademicYear.all
subcategories = Subcategory.all subcategories = Subcategory.all

@ -0,0 +1,5 @@
class AddSurveyItemResponsesCountToSurveyItem < ActiveRecord::Migration[7.0]
def change
add_column :survey_items, :survey_item_responses_count, :integer
end
end

@ -0,0 +1,9 @@
class ResetAllSurveyItemCacheCounters < ActiveRecord::Migration[7.0]
def up
SurveyItem.all.each do |survey_item|
SurveyItem.reset_counters(survey_item.id, :survey_item_responses)
end
end
def down; end
end

@ -0,0 +1,5 @@
class AddSurveyItemsCountToScales < ActiveRecord::Migration[7.0]
def change
add_column :scales, :survey_items_count, :integer
end
end

@ -0,0 +1,9 @@
class ResetAllScaleCacheCounters < ActiveRecord::Migration[7.0]
def up
Scale.all.each do |scale|
Scale.reset_counters(scale.id, :survey_items)
end
end
def down; end
end

@ -0,0 +1,5 @@
class AddScalesCountToMeasures < ActiveRecord::Migration[7.0]
def change
add_column :measures, :scales_count, :integer
end
end

@ -0,0 +1,9 @@
class ResetAllMeasureCacheCounters < ActiveRecord::Migration[7.0]
def up
Measure.all.each do |measure|
Measure.reset_counters(measure.id, :scales)
end
end
def down; end
end

@ -0,0 +1,5 @@
class AddMeasuresCountToSubcategories < ActiveRecord::Migration[7.0]
def change
add_column :subcategories, :measures_count, :integer
end
end

@ -0,0 +1,9 @@
class ResetAllSubcategoryCacheCounters < ActiveRecord::Migration[7.0]
def up
Subcategory.all.each do |subcategory|
Subcategory.reset_counters(subcategory.id, :measures)
end
end
def down; end
end

@ -0,0 +1,5 @@
class AddSubcategoriesCountToCategories < ActiveRecord::Migration[7.0]
def change
add_column :categories, :subcategories_count, :integer
end
end

@ -0,0 +1,9 @@
class ResetAllCategoryCacheCounters < ActiveRecord::Migration[7.0]
def up
Category.all.each do |category|
Category.reset_counters(category.id, :subcategories)
end
end
def down; end
end

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do ActiveRecord::Schema[7.0].define(version: 2022_06_16_220352) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -57,6 +57,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "category_id", null: false t.string "category_id", null: false
t.string "short_description" t.string "short_description"
t.integer "subcategories_count"
t.index ["slug"], name: "index_categories_on_slug", unique: true t.index ["slug"], name: "index_categories_on_slug", unique: true
end end
@ -283,6 +284,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do
t.text "description" t.text "description"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "scales_count"
t.index ["measure_id"], name: "index_measures_on_measure_id" t.index ["measure_id"], name: "index_measures_on_measure_id"
t.index ["subcategory_id"], name: "index_measures_on_subcategory_id" t.index ["subcategory_id"], name: "index_measures_on_subcategory_id"
end end
@ -319,6 +321,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do
t.bigint "measure_id", null: false t.bigint "measure_id", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "survey_items_count"
t.index ["measure_id"], name: "index_scales_on_measure_id" t.index ["measure_id"], name: "index_scales_on_measure_id"
t.index ["scale_id"], name: "index_scales_on_scale_id", unique: true t.index ["scale_id"], name: "index_scales_on_scale_id", unique: true
end end
@ -343,6 +346,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "subcategory_id", null: false t.string "subcategory_id", null: false
t.integer "measures_count"
end end
create_table "survey_item_responses", id: :serial, force: :cascade do |t| create_table "survey_item_responses", id: :serial, force: :cascade do |t|
@ -371,6 +375,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_211616) do
t.float "ideal_low_benchmark" t.float "ideal_low_benchmark"
t.bigint "scale_id", null: false t.bigint "scale_id", null: false
t.boolean "on_short_form", default: false t.boolean "on_short_form", default: false
t.integer "survey_item_responses_count"
t.index ["scale_id"], name: "index_survey_items_on_scale_id" t.index ["scale_id"], name: "index_survey_items_on_scale_id"
t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id" t.index ["survey_item_id"], name: "index_survey_items_on_survey_item_id"
end end

@ -49,9 +49,9 @@ namespace :data do
end end
desc 'refresh response rate values' desc 'refresh response rate values'
task refresh_response_rates: :environment do task reset_response_rates: :environment do
puts 'Refreshing response rates' puts 'Refreshing response rates'
ResponseRateLoader.refresh ResponseRateLoader.reset
puts "=====================> Completed loading #{ResponseRate.count} survey responses" puts "=====================> Completed loading #{ResponseRate.count} survey responses"
end end
@ -63,6 +63,31 @@ namespace :data do
end end
puts "=====================> Completed loading #{AdminDataValue.count} survey responses" puts "=====================> Completed loading #{AdminDataValue.count} survey responses"
end end
desc 'reset all cache counters'
task reset_cache_counters: :environment do
puts '=====================> Resetting Category counters'
Category.all.each do |category|
Category.reset_counters(category.id, :subcategories)
end
puts '=====================> Resetting Subcategory counters'
Subcategory.all.each do |subcategory|
Subcategory.reset_counters(subcategory.id, :measures)
end
puts '=====================> Resetting Measure counters'
Measure.all.each do |measure|
Measure.reset_counters(measure.id, :scales)
end
puts '=====================> Resetting Scale counters'
Scale.all.each do |scale|
Scale.reset_counters(scale.id, :survey_items)
end
puts '=====================> Resetting SurveyItem counters'
SurveyItem.all.each do |survey_item|
SurveyItem.reset_counters(survey_item.id, :survey_item_responses)
end
end
desc 'Load in all data' desc 'Load in all data'
task load: :environment do task load: :environment do
# return if School.count > 0 # return if School.count > 0

@ -44,7 +44,7 @@ describe ResponseRateLoader do
DatabaseCleaner.clean DatabaseCleaner.clean
end end
describe 'self.refresh' do describe 'self.reset' do
context 'When refreshing response rates' do context 'When refreshing response rates' do
context 'and half the students responded to each question' do context 'and half the students responded to each question' do
before :each do before :each do
@ -58,7 +58,7 @@ describe ResponseRateLoader do
create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:)
create_list(:survey_item_response, 5, survey_item: t_phya_q3, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: t_phya_q3, likert_score: 3, school:, academic_year:)
ResponseRateLoader.refresh ResponseRateLoader.reset
end end
it 'populates the database with response rates' do it 'populates the database with response rates' do
@ -76,7 +76,7 @@ describe ResponseRateLoader do
context 'when running the loader a second time' do context 'when running the loader a second time' do
it 'is idempotent' do it 'is idempotent' do
response_count = ResponseRate.count response_count = ResponseRate.count
ResponseRateLoader.refresh ResponseRateLoader.reset
second_count = ResponseRate.count second_count = ResponseRate.count
expect(response_count).to eq second_count expect(response_count).to eq second_count
@ -90,7 +90,7 @@ describe ResponseRateLoader do
create_list(:survey_item_response, 5, survey_item: s_poaf_q1, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: s_poaf_q1, likert_score: 3, school:, academic_year:)
create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:)
ResponseRateLoader.refresh ResponseRateLoader.reset
end end
it 'only takes into account the first question and ignores the other questions in the scale' do it 'only takes into account the first question and ignores the other questions in the scale' do
@ -106,7 +106,7 @@ describe ResponseRateLoader do
create_list(:survey_item_response, 5, survey_item: s_poaf_q1, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: s_poaf_q1, likert_score: 3, school:, academic_year:)
create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 5, survey_item: t_phya_q2, likert_score: 3, school:, academic_year:)
ResponseRateLoader.refresh ResponseRateLoader.reset
end end
it 'since no score can be calculated, it returns a default of 100' do it 'since no score can be calculated, it returns a default of 100' do
@ -128,7 +128,7 @@ describe ResponseRateLoader do
create_list(:survey_item_response, 1, survey_item: t_phya_q3, likert_score: 3, school:, academic_year:) create_list(:survey_item_response, 1, survey_item: t_phya_q3, likert_score: 3, school:, academic_year:)
short_form_survey short_form_survey
ResponseRateLoader.refresh ResponseRateLoader.reset
end end
it 'only counts responses from survey items on the short form' do it 'only counts responses from survey items on the short form' do

@ -107,7 +107,7 @@ describe 'analyze/index' do
end end
it 'displays disabled checkboxes for years that dont have data' do it 'displays disabled checkboxes for years that dont have data' do
ResponseRateLoader.refresh ResponseRateLoader.reset
year_checkbox = subject.css("##{academic_year.range}").first year_checkbox = subject.css("##{academic_year.range}").first
expect(year_checkbox.name).to eq 'input' expect(year_checkbox.name).to eq 'input'
expect(academic_year.range).to eq '2050-51' expect(academic_year.range).to eq '2050-51'

Loading…
Cancel
Save