I'm trying to write a class to handle the collecting and calculating of some data. My intention is to have the controller instantiate the Report object, and a very simple view display it. I figured this would keep the controller thin and keep logic out of the views.
class Report
def initialize(year_term_ids = [])
@year_term_ids = year_term_ids
end
def gpas
{}.tap do |gpas|
%i(average minimum maximum).each do |method|
gpas[method] = student_terms.send(method, :term_gpa).to_f.round(2)
end
end
end
def students
student_statuses.merge(
count: student_terms.count,
dismissed: student_terms.dismissed,
on_probation: student_terms.on_probation
)
end
def year_terms
@year_terms ||= load_year_terms
end
def student_terms
@student_terms ||= load_student_terms
end
private
def load_student_terms
StudentTerm.where(year_term: year_terms)
.includes(:student)
end
def load_year_terms
year_terms = YearTerm.includes(student_year_terms: [ :student ])
if @year_term_ids.empty?
year_terms
else
year_terms.where(id: @year_term_ids)
end
end
def student_statuses
symbolize_hash(student_terms.map(&:student).group_by(&:status))
end
def symbolize_hash(hash)
hash.keys.each do |k|
hash[k.underscore.to_sym] = hash.delete(k) if k.is_a?(String)
end
hash
end
end