A simple way to efficiently calculating and representing average data in Rails

Written on Feb 07, 2023

I'm working on a project and I encountered a scenario where I need to calculate the average marks of students and create a simple visualization indicator to represent the calculated average. After a few iterations, I found this can be accomplished through a simple implementation and subsequent refactoring of the code.


Let's say you have a Student model studen.rb and AcadmicReport model academic_report.rb . You want to show student's average marks in student show view, but the marks is an attribute of the academic_report model.

Initially, you may write a method to calculate the average marks, which can be done by iterating through the student's academic reports and summing the marks. You can then divide the sum by the number of academic reports to get the average marks.

# student.rb
def average_marks(marks)   
    marks.sum / marks.length 

Next, you can create a method to assign the stars for the calculated average marks. This can be done through a simple case statement that assigns a certain number of stars based on the range of the average marks.

# academic_reports_helper.rb
    case average 
    when 0..40 
        stars = 1 
    when 41..60 
        stars = 2
    when 61..80 
        stars = 3 
    when 81..90 
        stars = 4 
    else stars = 5 

    "⭐ " * stars

Finally, you can render the stars in your student show view using the two methods.

# views/students/show.html.erb
<%= stars_for_average_marks(average_marks(@student.academic_reports.map { |report| report.marks })) %>


While this implementation works, it can be further optimized and refactored. For example, you can add a method in the Student model to calculate the average marks and then call that method in the view. This helps keep your code clean and organized and makes it easier to maintain and understand when you visit it later.

# in the Student model 
def average_academic_marks   
    academic_reports.sum(:marks) / academic_reports.count 

# in the student show view 
<%= stars_for_average_marks(@student.average_academic_marks) %>

As you see, Rails helps calculate the average marks of students (or a model you work with), and create a simple visualization indicator, and it can be done through a simple implementation. By refactoring the code and moving the calculation to the Student model, you can improve the readability and maintainability of your code.


In addition to the average_academic_marks method, we can also calculate the average marks in percentage form. This is easily done with the use of the average_academic_marks method. Simply create a new method called average_academic_marks_percentage and add the necessary calculation as below:

# student.rb
def average_academic_marks_percentage
    average_academic_marks.round(2).to_s + '%' # 100 is the maximum marks 

With this new method, we now have the ability to access both the average marks in numerical form as well as in percentage form. This adds another layer of insight and information that can be used to better understand and analyze student performance. And it is a nice feature, teachers love it.

In conclusion, by refactoring our initial code and moving the calculation logic into the Student model, we have made our code cleaner, more maintainable, and easily extendable for future needs.

And as usual, Happy Coding 😀 💻

Subscribe to Design and Develpment ideas

Enter your email to subscribe to a once-monthly newsletter curating the latest content on Rails, Hotwire, and other things you might find interesting.

Get in touch