Refactor code based on rubocop and reek suggestions

pull/1/head
rebuilt 3 years ago
parent 1737122c80
commit bb5f668497

@ -2,3 +2,5 @@
detectors:
InstanceVariableAssumption:
enabled: false
IrresponsibleModule:
enabled: false

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AnalyzeController < SqmApplicationController
def index
assign_categories
@ -19,7 +21,7 @@ class AnalyzeController < SqmApplicationController
end
def assign_measures
@measures = @subcategory.measures.order(:measure_id).includes(%i[scales admin_data_items subcategory])
@measures = @subcategory.measures.order(:measure_id).includes(%i[subcategory])
end
def assign_academic_years

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ApplicationController < ActionController::Base
before_action :set_google_analytics_id
before_action :set_hotjar_id

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CategoriesController < SqmApplicationController
helper GaugeHelper
def show

@ -1,3 +1,5 @@
# frozen_string_literal: true
class HomeController < ApplicationController
helper HeaderHelper
def index

@ -1,3 +1,5 @@
# frozen_string_literal: true
class OverviewController < SqmApplicationController
before_action :check_empty_dataset, only: [:index]
helper VarianceHelper
@ -16,7 +18,7 @@ class OverviewController < SqmApplicationController
end
def check_empty_dataset
@has_empty_dataset = !subcategories.any? do |subcategory|
@has_empty_dataset = subcategories.none? do |subcategory|
response_rate = subcategory.response_rate(school: @school, academic_year: @academic_year)
response_rate.meets_student_threshold || response_rate.meets_teacher_threshold
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class SqmApplicationController < ApplicationController
protect_from_forgery with: :exception, prepend: true
before_action :set_schools_and_districts

@ -1,3 +1,5 @@
# frozen_string_literal: true
module AnalyzeHelper
def zone_label_width
15
@ -73,7 +75,7 @@ module AnalyzeHelper
def empty_dataset?(measures:, school:, academic_year:)
@empty_dataset ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = !measures.any? do |measure|
memo[[school, academic_year]] = measures.none? do |measure|
response_rate = measure.subcategory.response_rate(school:, academic_year:)
response_rate.meets_student_threshold || response_rate.meets_teacher_threshold
end

@ -1,2 +0,0 @@
module ColorHelper
end

@ -46,7 +46,7 @@ module HeaderHelper
true).joins('inner join academic_years a on response_rates.academic_year_id=a.id').order('a.range DESC').first
academic_year = latest_response_rate.academic_year if latest_response_rate.present?
academic_year ||= AcademicYear.order('range DESC').first
academic_year || AcademicYear.order('range DESC').first
end
def link_weight(path:)

@ -1,3 +1,5 @@
# frozen_string_literal: true
module VarianceHelper
def heading_gutter
30

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AcademicYear < ActiveRecord::Base
def self.find_by_date(date)
if date.month > 6

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AdminDataItem < ActiveRecord::Base
belongs_to :scale
has_many :admin_data_values

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AdminDataValue < ApplicationRecord
belongs_to :school
belongs_to :admin_data_item

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Category < ActiveRecord::Base
include FriendlyId
friendly_id :name, use: [:slugged]

@ -1,2 +1,4 @@
# frozen_string_literal: true
class DataAvailability < Struct.new(:id, :description, :available?)
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class District < ApplicationRecord
has_many :schools

@ -1,3 +1,5 @@
# frozen_string_literal: true
module Legacy
def self.table_name_prefix
'legacy_'

@ -62,6 +62,8 @@ class Measure < ActiveRecord::Base
end
def score(school:, academic_year:)
# average = SurveyItemResponse.where(school:, academic_year:).first
# Score.new(average, false, false, false)
@score ||= Hash.new do |memo, (school, academic_year)|
next Score::NIL_SCORE if incalculable_score(school:, academic_year:)
@ -197,25 +199,33 @@ class Measure < ActiveRecord::Base
end
def no_student_responses_exist?(school:, academic_year:)
student_survey_items_by_survey_type(school:,
academic_year:).all? do |survey_item|
survey_item.survey_item_responses.where(school:,
academic_year:).none?
@no_student_responses_exist ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = student_survey_items_by_survey_type(school:, academic_year:).all? do |survey_item|
survey_item.survey_item_responses.where(school:, academic_year:).none?
end
end
@no_student_responses_exist[[school, academic_year]]
end
def no_teacher_responses_exist?(school:, academic_year:)
teacher_survey_items.all? do |survey_item|
survey_item.survey_item_responses.where(school:,
academic_year:).none?
@no_teacher_responses_exist ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = teacher_survey_items.all? do |survey_item|
survey_item.survey_item_responses.where(school:,
academic_year:).none?
end
end
@no_teacher_responses_exist[[school, academic_year]]
end
def incalculable_score(school:, academic_year:)
meets_student_threshold = sufficient_student_data?(school:, academic_year:)
meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:)
lacks_sufficient_survey_data = !meets_student_threshold && !meets_teacher_threshold
lacks_sufficient_survey_data && !includes_admin_data_items?
@incalculable_score ||= Hash.new do |memo, (school, academic_year)|
meets_student_threshold = sufficient_student_data?(school:, academic_year:)
meets_teacher_threshold = sufficient_teacher_data?(school:, academic_year:)
lacks_sufficient_survey_data = !meets_student_threshold && !meets_teacher_threshold
memo[[school, academic_year]] = lacks_sufficient_survey_data && !includes_admin_data_items?
end
@incalculable_score[[school, academic_year]]
end
def collect_averages_for_teacher_student_and_admin_data(school:, academic_year:)
@ -227,15 +237,26 @@ class Measure < ActiveRecord::Base
end
def teacher_average(school:, academic_year:)
collect_survey_item_average(survey_items: teacher_survey_items, school:, academic_year:)
@teacher_average ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] =
collect_survey_item_average(survey_items: teacher_survey_items, school:, academic_year:)
end
@teacher_average[[school, academic_year]]
end
def student_average(school:, academic_year:)
collect_survey_item_average(survey_items: student_survey_items_by_survey_type(school:, academic_year:), school:,
academic_year:)
@student_average ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = collect_survey_item_average(survey_items: student_survey_items_by_survey_type(school:, academic_year:), school:,
academic_year:)
end
@student_average[[school, academic_year]]
end
def admin_data_averages(school:, academic_year:)
collect_admin_scale_average(admin_data_items:, school:, academic_year:)
@admin_data_averages ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = collect_admin_scale_average(admin_data_items:, school:, academic_year:)
end
@admin_data_averages[[school, academic_year]]
end
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Respondent < ApplicationRecord
belongs_to :school
belongs_to :academic_year

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ResponseRate < ApplicationRecord
belongs_to :subcategory
belongs_to :school

@ -1,3 +1,5 @@
# frozen_string_literal: true
module ResponseRateCalculator
TEACHER_RATE_THRESHOLD = 25
STUDENT_RATE_THRESHOLD = 25
@ -19,7 +21,7 @@ module ResponseRateCalculator
return 0 unless total_possible_responses.positive?
response_rate = (average_responses_per_survey_item / total_possible_responses.to_f * 100).round
cap_at_100(response_rate)
cap_at_one_hundred(response_rate)
end
def meets_student_threshold?
@ -32,7 +34,7 @@ module ResponseRateCalculator
private
def cap_at_100(response_rate)
def cap_at_one_hundred(response_rate)
response_rate > 100 ? 100 : response_rate
end
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Scale < ApplicationRecord
belongs_to :measure, counter_cache: true
has_many :survey_items
@ -38,8 +40,9 @@ class Scale < ApplicationRecord
def student_survey_items(school:, academic_year:)
survey = Survey.where(school:, academic_year:).first
return survey_items.student_survey_items.short_form_items if survey.present? && survey.form == 'short'
student_survey_items = survey_items.student_survey_items
return student_survey_items.short_form_items if survey.present? && survey.form == 'short'
survey_items.student_survey_items
student_survey_items
end
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class School < ApplicationRecord
belongs_to :district

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Score < Struct.new(:average, :meets_teacher_threshold?, :meets_student_threshold?, :meets_admin_data_threshold?)
NIL_SCORE = Score.new(nil, false, false, false)
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class StudentResponseRateCalculator
include ResponseRateCalculator

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Subcategory < ActiveRecord::Base
belongs_to :category, counter_cache: true

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Survey < ApplicationRecord
belongs_to :academic_year
belongs_to :school

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

@ -1,3 +1,5 @@
# frozen_string_literal: true
class SurveyItemResponse < ActiveRecord::Base
TEACHER_RESPONSE_THRESHOLD = 2
STUDENT_RESPONSE_THRESHOLD = 2

@ -1,3 +1,5 @@
# frozen_string_literal: true
class TeacherResponseRateCalculator
include ResponseRateCalculator

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AdminDataPresenter < DataItemPresenter
def initialize(measure_id:, admin_data_items:, has_sufficient_data:, school:, academic_year:)
super(measure_id:, has_sufficient_data:, school:, academic_year:)

@ -1,3 +1,5 @@
# frozen_string_literal: true
class AnalyzeBarPresenter
include AnalyzeHelper
attr_reader :score, :x_position, :academic_year, :measure_id, :measure, :color
@ -45,7 +47,8 @@ class AnalyzeBarPresenter
end
def percentage
(score.average - zone.low_benchmark) / (zone.high_benchmark - zone.low_benchmark)
low_benchmark = zone.low_benchmark
(score.average - low_benchmark) / (zone.high_benchmark - low_benchmark)
end
def zone
@ -59,9 +62,10 @@ class AnalyzeBarPresenter
end
def average
return 0 if score.average.nil?
average = score.average
return 0 if average.nil?
score.average.round(6)
average.round(6)
end
private

@ -1,3 +1,5 @@
# frozen_string_literal: true
class CategoryPresenter
def initialize(category:)
@category = category
@ -24,34 +26,12 @@ class CategoryPresenter
end
def icon_class
icon_suffix = case name
when 'Teachers & Leadership'
'apple-alt'
when 'School Culture'
'school'
when 'Resources'
'users-cog'
when 'Academic Learning'
'graduation-cap'
when 'Community & Wellbeing'
'heart'
end
icon_suffix = classes[name.to_sym]
"fas fa-#{icon_suffix}"
end
def icon_color_class
color_suffix = case name
when 'Teachers & Leadership'
'blue'
when 'School Culture'
'red'
when 'Resources'
'black'
when 'Academic Learning'
'lime'
when 'Community & Wellbeing'
'teal'
end
color_suffix = colors[name.to_sym]
"color-#{color_suffix}"
end
@ -68,4 +48,22 @@ class CategoryPresenter
def to_model
@category
end
private
def colors
{ 'Teachers & Leadership': 'blue',
'School Culture': 'red',
'Resources': 'black',
'Academic Learning': 'lime',
'Community & Wellbeing': 'teal' }
end
def classes
{ 'Teachers & Leadership': 'apple-alt',
'School Culture': 'school',
'Resources': 'users-cog',
'Academic Learning': 'graduation-cap',
'Community & Wellbeing': 'heart' }
end
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class DataItemPresenter
attr_reader :measure_id, :has_sufficient_data, :school, :academic_year

@ -1,3 +1,5 @@
# frozen_string_literal: true
class GaugePresenter
def initialize(zones:, score:)
@zones = zones

@ -1,6 +1,7 @@
# frozen_string_literal: true
class GroupedBarColumnPresenter
include AnalyzeHelper
include ColorHelper
attr_reader :measure_name, :measure_id, :category, :position, :measure, :school, :academic_years
@ -86,8 +87,8 @@ class GroupedBarColumnPresenter
[year, score(index)]
end
yearly_scores.reject do |yearly_score|
score = yearly_score[1]
score.average.nil? || score.average.zero? || score.average.nan?
average = yearly_score[1].average
average.nil? || average.zero? || average.nan?
end
end
@ -97,6 +98,7 @@ class GroupedBarColumnPresenter
end
def bar_x(index)
column_start_x + (index * bar_width * 1.2) + ((column_end_x - column_start_x) - (yearly_scores.size * bar_width * 1.2)) / 2
column_start_x + (index * bar_width * 1.2) +
((column_end_x - column_start_x) - (yearly_scores.size * bar_width * 1.2)) / 2
end
end

@ -1,22 +1,15 @@
# frozen_string_literal: true
class MeasurePresenter
attr_reader :measure, :academic_year, :school
attr_reader :measure, :academic_year, :school, :id, :name, :description
def initialize(measure:, academic_year:, school:)
@measure = measure
@academic_year = academic_year
@school = school
end
def id
@measure.measure_id
end
def name
@measure.name
end
def description
@measure.description
@id = measure_id
@name = measure.name
@description = measure.description
end
def gauge_presenter
@ -29,27 +22,49 @@ class MeasurePresenter
def data_item_presenters
[].tap do |array|
if @measure.student_survey_items.any?
array << StudentSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.student_survey_items,
has_sufficient_data: score_for_measure.meets_student_threshold?, school:, academic_year:)
end
if @measure.teacher_survey_items.any?
array << TeacherSurveyPresenter.new(measure_id: @measure.measure_id, survey_items: @measure.teacher_survey_items,
has_sufficient_data: score_for_measure.meets_teacher_threshold?, school:, academic_year:)
end
if @measure.admin_data_items.any?
array << AdminDataPresenter.new(measure_id: @measure.measure_id,
admin_data_items: @measure.admin_data_items, has_sufficient_data: score_for_measure.meets_admin_data_threshold?, school:, academic_year:)
end
array << student_survey_presenter if student_survey_items.any?
array << teacher_survey_presenter if teacher_survey_items.any?
array << admin_data_presenter if admin_data_items.any?
end
end
private
def admin_data_items
measure.admin_data_items
end
def score_for_measure
@score ||= @measure.score(school: @school, academic_year: @academic_year)
end
def student_survey_items
measure.student_survey_items
end
def teacher_survey_items
measure.teacher_survey_items
end
def measure_id
measure.measure_id
end
def student_survey_presenter
StudentSurveyPresenter.new(measure_id:, survey_items: student_survey_items,
has_sufficient_data: score_for_measure.meets_student_threshold?, school:, academic_year:)
end
def teacher_survey_presenter
TeacherSurveyPresenter.new(measure_id:, survey_items: teacher_survey_items,
has_sufficient_data: score_for_measure.meets_teacher_threshold?, school:, academic_year:)
end
def admin_data_presenter
AdminDataPresenter.new(measure_id:,
admin_data_items:, has_sufficient_data: score_for_measure.meets_admin_data_threshold?, school:, academic_year:)
end
def zones
Zones.new(
watch_low_benchmark: @measure.watch_low_benchmark,

@ -1,3 +1,5 @@
# frozen_string_literal: true
class StudentGroupedBarColumnPresenter < GroupedBarColumnPresenter
def label
'All Students'

@ -1,3 +1,5 @@
# frozen_string_literal: true
class StudentSurveyPresenter < DataItemPresenter
attr_reader :survey_items

@ -1,3 +1,5 @@
# frozen_string_literal: true
class SubcategoryCardPresenter
attr_reader :name, :subcategory, :category, :subcategory_id

@ -1,20 +1,15 @@
# frozen_string_literal: true
class SubcategoryPresenter
attr_reader :subcategory, :academic_year, :school, :id, :name, :description
def initialize(subcategory:, academic_year:, school:)
@subcategory = subcategory
@academic_year = academic_year
@school = school
end
def id
@subcategory.subcategory_id
end
def name
@subcategory.name
end
def description
@subcategory.description
@id = @subcategory.subcategory_id
@name = @subcategory.name
@description = @subcategory.description
end
def gauge_presenter
@ -65,9 +60,10 @@ class SubcategoryPresenter
end
def admin_data_item_count
return AdminDataItem.for_measures(@subcategory.measures).count if @school.is_hs
measures = @subcategory.measures
return AdminDataItem.for_measures(measures).count if @school.is_hs
AdminDataItem.non_hs_items_for_measures(@subcategory.measures).count
AdminDataItem.non_hs_items_for_measures(measures).count
end
def format_a_non_applicable_rate(rate)

@ -1,3 +1,5 @@
# frozen_string_literal: true
class TeacherGroupedBarColumnPresenter < GroupedBarColumnPresenter
def label
'All Teachers'

@ -1,3 +1,5 @@
# frozen_string_literal: true
class TeacherSurveyPresenter < DataItemPresenter
attr_reader :survey_items

@ -1,3 +1,5 @@
# frozen_string_literal: true
class VarianceChartRowPresenter
include Comparable

@ -1,3 +1,5 @@
# frozen_string_literal: true
class Zones
def initialize(watch_low_benchmark:, growth_low_benchmark:, approval_low_benchmark:, ideal_low_benchmark:)
@watch_low_benchmark = watch_low_benchmark
@ -7,7 +9,19 @@ class Zones
@warning_low_benchmark = 1
end
Zone = Struct.new(:low_benchmark, :high_benchmark, :type)
Zone = Struct.new(:low_benchmark, :high_benchmark, :type) do
def contains?(number)
return false if number.nil? || number.is_a?(Float) && number.nan?
number.between?(low_benchmark, high_benchmark)
end
end
def all_zones
[
ideal_zone, approval_zone, growth_zone, watch_zone, warning_zone, insufficient_data
]
end
def warning_zone
Zone.new(1, @watch_low_benchmark, :warning)
@ -30,26 +44,10 @@ class Zones
end
def insufficient_data
Zone.new(0, @warning_low_benchmark, :insufficient_data)
Zone.new(Float::MIN, Float::MAX, :insufficient_data)
end
def zone_for_score(score)
return insufficient_data if score.nil?
return insufficient_data if score.is_a?(Float) && score.nan?
case score
when ideal_zone.low_benchmark..ideal_zone.high_benchmark
ideal_zone
when approval_zone.low_benchmark..approval_zone.high_benchmark
approval_zone
when growth_zone.low_benchmark..growth_zone.high_benchmark
growth_zone
when watch_zone.low_benchmark..watch_zone.high_benchmark
watch_zone
when 1..warning_zone.high_benchmark
warning_zone
else
insufficient_data
end
all_zones.find { |zone| zone.contains?(score) } || insufficient_data
end
end

@ -1,26 +1,18 @@
# frozen_string_literal: true
require 'csv'
class AdminDataLoader
def self.load_data(filepath:)
CSV.parse(File.read(filepath), headers: true) do |row|
likert_score = row['LikertScore'] || row['Likert Score'] || row['Likert_Score']
likert_score = likert_score.to_f
likert_score = 1 if likert_score > 0 && likert_score < 1
unless valid_likert_score(likert_score:)
puts "This value is not valid #{likert_score}"
score = likert_score(row:)
unless valid_likert_score(likert_score: score)
puts "Invalid score: #{score}
for school: #{School.find_by_dese_id(row['DESE ID']).name}
admin data item #{admin_data_item(row:)} "
next
end
ay = row['Academic Year'] || row['AcademicYear']
dese_id = row['DESE ID'] || row['Dese ID'] || row['Dese Id']
admin_data_item_id = row['Item ID'] || row['Item Id']
admin_data_value = AdminDataValue.new
admin_data_value.likert_score = likert_score
admin_data_value.academic_year = AcademicYear.find_by_range ay
admin_data_value.school = School.find_by_dese_id dese_id.to_i
admin_data_value.admin_data_item = AdminDataItem.find_by_admin_data_item_id admin_data_item_id
admin_data_value.save!
create_admin_data_value(row:, score:)
end
end
@ -28,5 +20,33 @@ class AdminDataLoader
likert_score >= 1 && likert_score <= 5
end
def self.likert_score(row:)
likert_score = row['LikertScore'] || row['Likert Score'] || row['Likert_Score']
likert_score = likert_score.to_f
likert_score = 1 if likert_score.positive? && likert_score < 1
likert_score
end
def self.ay(row:)
row['Academic Year'] || row['AcademicYear']
end
def self.dese_id(row:)
row['DESE ID'] || row['Dese ID'] || row['Dese Id']
end
def self.admin_data_item(row:)
row['Item ID'] || row['Item Id']
end
def self.create_admin_data_value(row:, score:)
admin_data_value = AdminDataValue.new
admin_data_value.likert_score = score
admin_data_value.academic_year = AcademicYear.find_by_range ay(row:)
admin_data_value.school = School.find_by_dese_id dese_id(row:).to_i
admin_data_value.admin_data_item = AdminDataItem.find_by_admin_data_item_id admin_data_item(row:)
admin_data_value.save!
end
private_class_method :valid_likert_score
end

@ -1,3 +1,5 @@
# frozen_string_literal: true
class ResponseRateLoader
def self.reset(schools: School.all, academic_years: AcademicYear.all, subcategories: Subcategory.all)
milford = School.find_by_slug 'milford-high-school'

@ -1,10 +1,12 @@
# frozen_string_literal: true
require 'csv'
class SurveyResponsesDataLoader
def self.load_data(filepath:)
File.open(filepath) do |file|
headers = file.first
survey_items = SurveyItem.where(survey_item_id: get_survey_item_ids_from_headers(file:, headers:))
survey_items = SurveyItem.where(survey_item_id: get_survey_item_ids_from_headers(headers:))
file.lazy.each_slice(1000) do |lines|
survey_item_responses = CSV.parse(lines.join, headers:).map do |row|
@ -19,43 +21,42 @@ class SurveyResponsesDataLoader
private
def self.process_row(row:, survey_items:)
return unless dese_id?(row['DESE ID'])
id = dese_id(row)
return unless dese_id?(id)
school = School.find_by_dese_id(row['DESE ID'])
school = School.find_by_dese_id(id)
return unless school.present?
process_survey_items(row:, survey_items:, school:)
end
def self.process_survey_items(row:, survey_items:, school:)
response_id = row['Response ID'] || row['ResponseId'] || row['ResponseID']
id = response_id(row)
survey_items.map do |survey_item|
likert_score = row[survey_item.survey_item_id]
next if likert_score.nil?
likert_score = row[survey_item.survey_item_id] || next
unless likert_score.valid_likert_score?
puts "Response ID: #{response_id}, Likert score: #{likert_score} rejected" unless likert_score == 'NA'
puts "Response ID: #{id}, Likert score: #{likert_score} rejected" unless likert_score == 'NA'
next
end
survey_item_response = SurveyItemResponse.where(response_id:, survey_item:).first
create_or_update_survey_item_response(survey_item_response:, likert_score:, school:, response_id:, row:,
survey_item:)
response = survey_item_response(response_id: id, survey_item:)
create_or_update_response(survey_item_response: response, likert_score:, school:, row:, survey_item:)
end.compact
end
def self.create_or_update_survey_item_response(survey_item_response:, likert_score:, school:, row:, survey_item:, response_id:)
def self.create_or_update_response(survey_item_response:, likert_score:, school:, row:, survey_item:)
if survey_item_response.present?
survey_item_response.update!(likert_score:) if survey_item_response.likert_score != likert_score
[]
else
SurveyItemResponse.new(response_id:, academic_year: academic_year(row), school:, survey_item:, likert_score:)
SurveyItemResponse.new(response_id: response_id(row), academic_year: academic_year(row), school:, survey_item:,
likert_score:)
end
end
def self.get_survey_item_ids_from_headers(file:, headers:)
def self.get_survey_item_ids_from_headers(headers:)
CSV.parse(headers, headers: true).headers
.filter { |header| header.present? }
.filter(&:present?)
.filter { |header| header.start_with? 't-' or header.start_with? 's-' }
end
@ -71,10 +72,28 @@ class SurveyResponsesDataLoader
AcademicYear.find_by_date response_date(row)
end
def self.survey_item_response(response_id:, survey_item:)
SurveyItemResponse.find_by(response_id:, survey_item:)
end
def self.response_id(row)
row['Response ID'] || row['ResponseId'] || row['ResponseID']
end
def self.dese_id(row)
row['DESE ID' || 'Dese ID'] || row['DeseId'] || row['DeseID']
end
private_class_method :process_row
private_class_method :process_survey_items
private_class_method :get_survey_item_ids_from_headers
private_class_method :dese_id?
private_class_method :create_or_update_response
private_class_method :response_date
private_class_method :academic_year
private_class_method :survey_item_response
private_class_method :response_id
private_class_method :dese_id
end
module StringMonkeyPatches

@ -64,7 +64,7 @@ describe AdminDataLoader do
describe 'output to console' do
it 'outputs a messsage saying a value has been rejected' do
output = capture_stdout { AdminDataLoader.load_data filepath: path_to_admin_data }.gsub("\n", '')
expect(output).to eq 'This value is not valid 0.0This value is not valid 100.0'
expect(output).to eq 'Invalid score: 0.0 for school: Attleboro High School admin data item a-reso-i1 Invalid score: 100.0 for school: Winchester High School admin data item a-sust-i3 '
end
end
end

Loading…
Cancel
Save