mirror of
https://github.com/edcommonwealth/sqm-dashboards.git
synced 2026-03-07 21:48:16 -08:00
working on aggregated results
This commit is contained in:
parent
f5b473ed28
commit
48eb55ad94
11 changed files with 120 additions and 8 deletions
|
|
@ -7,6 +7,11 @@ class Attempt < ApplicationRecord
|
|||
belongs_to :recipient_schedule
|
||||
belongs_to :question
|
||||
|
||||
after_save :update_school_categories
|
||||
|
||||
scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) }
|
||||
scope :for_school, -> (school) { joins(:recipient).merge(Recipient.for_school(school)) }
|
||||
|
||||
def send_message
|
||||
twilio_number = ENV['TWILIO_NUMBER']
|
||||
client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']
|
||||
|
|
@ -21,4 +26,14 @@ class Attempt < ApplicationRecord
|
|||
recipient.update_attributes(phone: client.messages.get(message.sid).to)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_school_categories
|
||||
school_category = SchoolCategory.for(recipient.school, question.category).first
|
||||
if school_category.nil?
|
||||
school_category = SchoolCategory.create(school: recipient.school, category: question.category)
|
||||
end
|
||||
# school_category.aggregate_responses
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ class Question < ApplicationRecord
|
|||
validates :option4, presence: true
|
||||
validates :option5, presence: true
|
||||
|
||||
scope :for_category, -> (category) { where(category: category) }
|
||||
|
||||
|
||||
def options
|
||||
[option1, option2, option3, option4, option5].map(&:downcase).map(&:strip)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class Recipient < ApplicationRecord
|
|||
|
||||
validates :name, presence: true
|
||||
|
||||
scope :for_school, -> (school) { where(school: school) }
|
||||
|
||||
before_destroy :sync_lists
|
||||
|
||||
def self.import(school, file)
|
||||
|
|
|
|||
27
app/models/school_category.rb
Normal file
27
app/models/school_category.rb
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
class SchoolCategory < ApplicationRecord
|
||||
|
||||
belongs_to :school
|
||||
belongs_to :category
|
||||
|
||||
scope :for, -> (school, category) { where(school: school).where(category: category) }
|
||||
|
||||
def aggregated_responses
|
||||
attempt_data = Attempt.
|
||||
for_category(category).
|
||||
for_school(school).
|
||||
select('count(attempts.id) as attempt_count').
|
||||
select('count(attempts.answer_index) as response_count').
|
||||
select('sum(attempts.answer_index) as answer_index_total')[0]
|
||||
|
||||
return {
|
||||
attempt_count: attempt_data.attempt_count,
|
||||
response_count: attempt_data.response_count,
|
||||
answer_index_total: attempt_data.answer_index_total
|
||||
}
|
||||
end
|
||||
|
||||
def aggregate_responses
|
||||
return if ENV['BULK_PROCESS']
|
||||
|
||||
end
|
||||
end
|
||||
13
db/migrate/20170312202259_create_school_categories.rb
Normal file
13
db/migrate/20170312202259_create_school_categories.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class CreateSchoolCategories < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :school_categories do |t|
|
||||
t.references :school, foreign_key: true
|
||||
t.references :category, foreign_key: true
|
||||
t.integer :attempt_count
|
||||
t.integer :response_count
|
||||
t.integer :answer_index_total
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
16
db/schema.rb
16
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170311195824) do
|
||||
ActiveRecord::Schema.define(version: 20170312202259) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -122,6 +122,18 @@ ActiveRecord::Schema.define(version: 20170311195824) do
|
|||
t.index ["school_id"], name: "index_schedules_on_school_id", using: :btree
|
||||
end
|
||||
|
||||
create_table "school_categories", force: :cascade do |t|
|
||||
t.integer "school_id"
|
||||
t.integer "category_id"
|
||||
t.integer "attempt_count"
|
||||
t.integer "response_count"
|
||||
t.integer "answer_index_total"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["category_id"], name: "index_school_categories_on_category_id", using: :btree
|
||||
t.index ["school_id"], name: "index_school_categories_on_school_id", using: :btree
|
||||
end
|
||||
|
||||
create_table "schools", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.integer "district_id"
|
||||
|
|
@ -149,4 +161,6 @@ ActiveRecord::Schema.define(version: 20170311195824) do
|
|||
|
||||
add_foreign_key "recipient_lists", "schools"
|
||||
add_foreign_key "schedules", "schools"
|
||||
add_foreign_key "school_categories", "categories"
|
||||
add_foreign_key "school_categories", "schools"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -202,6 +202,6 @@ namespace :data do
|
|||
end
|
||||
ENV.delete('BULK_PROCESS')
|
||||
|
||||
# SchoolMeasure.all.each { |sm| sm.calculate_measurements }
|
||||
SchoolCategory.all.each { |sc| sc.aggregate_responses }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ RSpec.describe AttemptsController, type: :controller do
|
|||
let(:valid_session) { {} }
|
||||
|
||||
let(:schedule) { Schedule.new }
|
||||
let(:recipient) { Recipient.create(name: 'Recipient', phone: '+11231231234') }
|
||||
let(:school) { School.create!(name: 'School') }
|
||||
let(:recipient) { Recipient.create!(name: 'Recipient', phone: '+11231231234') }
|
||||
let(:recipient_schedule) { RecipientSchedule.new }
|
||||
let(:question) { Question.new }
|
||||
let(:category) { Category.create!(name: 'Category') }
|
||||
let(:question) { create_questions(1, category).first }
|
||||
let!(:first_attempt) {
|
||||
Attempt.create(
|
||||
schedule: schedule,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ describe "survey:attempt_questions" do
|
|||
school.recipient_lists.create!(name: 'Parents', recipient_ids: recipients.map(&:id).join(','))
|
||||
end
|
||||
|
||||
let!(:questions) { create_questions(3) }
|
||||
let!(:category) { Category.create(name: 'Category') }
|
||||
let!(:questions) { create_questions(3, category) }
|
||||
let!(:question_list) do
|
||||
QuestionList.create!(name: 'Parent Questions', question_ids: questions.map(&:id).join(','))
|
||||
end
|
||||
|
|
@ -86,7 +87,7 @@ describe "survey:attempt_questions" do
|
|||
|
||||
describe 'A Week Later' do
|
||||
before :each do
|
||||
Timecop.freeze(Date.today + 8) { subject.invoke }
|
||||
Timecop.freeze(Date.today + 10) { subject.invoke }
|
||||
end
|
||||
|
||||
it 'should create the second attempt for each recipient with a different question' do
|
||||
|
|
|
|||
34
spec/models/school_category_spec.rb
Normal file
34
spec/models/school_category_spec.rb
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SchoolCategory, type: :model do
|
||||
|
||||
let!(:school1) { School.create!(name: 'School 1') }
|
||||
let!(:school2) { School.create!(name: 'School 2') }
|
||||
|
||||
let!(:school1recipients) { create_recipients(school1, 4) }
|
||||
let!(:school2recipients) { create_recipients(school2, 4) }
|
||||
|
||||
let!(:category1) { Category.create!(name: 'Category 1') }
|
||||
let!(:category2) { Category.create!(name: 'Category 2') }
|
||||
|
||||
let!(:questions) { create_questions(3, category1) }
|
||||
|
||||
let!(:attempt1) { Attempt.create(question: questions[0], recipient: school1recipients[0], answer_index: 2)}
|
||||
let!(:attempt2) { Attempt.create(question: questions[0], recipient: school1recipients[1])}
|
||||
let!(:attempt3) { Attempt.create(question: questions[0], recipient: school1recipients[2], answer_index: 3)}
|
||||
let!(:attempt4) { Attempt.create(question: questions[0], recipient: school2recipients[0], answer_index: 4)}
|
||||
|
||||
let!(:school_category) { SchoolCategory.for(school1, category1).first }
|
||||
|
||||
describe 'aggregated_responses' do
|
||||
it 'should provide the count and sum of all attempts' do
|
||||
expect(school_category.aggregated_responses).to eq(
|
||||
attempt_count: 3,
|
||||
response_count: 2,
|
||||
answer_index_total: 5
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -146,7 +146,7 @@ def create_recipients(school, count)
|
|||
return recipients
|
||||
end
|
||||
|
||||
def create_questions(count)
|
||||
def create_questions(count, category=nil)
|
||||
questions = []
|
||||
count.times do |i|
|
||||
questions << Question.create(
|
||||
|
|
@ -155,7 +155,8 @@ def create_questions(count)
|
|||
option2: "Option #{i}:#{count} B",
|
||||
option3: "Option #{i}:#{count} C",
|
||||
option4: "Option #{i}:#{count} D",
|
||||
option5: "Option #{i}:#{count} E"
|
||||
option5: "Option #{i}:#{count} E",
|
||||
category: category
|
||||
)
|
||||
end
|
||||
return questions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue