Search code examples
ruby-on-rails-3activerecordnormalization

Grouping, totaling in Rails and Active Record


I'm trying to group a series of records in Active Record so I can do some calculations to normalize that quantity attribute of each record for example:

A user enters a date and a quantity. Dates are not unique, so I may have 10 - 20 quantities for each date. I need to work with only the totals for each day, not every individual record. Because then, after determining the highest and lowest value, I convert each one by basically dividing by n which is usually 10.

This is what I'm doing right now:

def heat_map(project, word_count, n_div)
    return "freezing" if word_count == 0
    words = project.words
    counts = words.map(&:quantity)
    max = counts.max
    min = counts.min
    return "max" if word_count == max
    return "min" if word_count == min
    break_point = (max - min).to_f/n_div.to_f
    heat_index = (((word_count - min).to_f)/break_point).to_i  
end

This works great if I display a table of all the word counts, but I'm trying to apply the heat map to a calendar that displays running totals for each day. This obviously doesn't total the days, so I end up with numbers that are out of the normal scale.

I can't figure out a way to group the word counts and total them by day before I do the normalization. I tried doing a group_by and then adding the map call, but I got an error an undefined method error. Any ideas? I'm also open to better / cleaner ways of normalizing the word counts, too.


Solution

  • Hard to answer without knowing a bit more about your models. So I'm going to assume that the date you're interested in is just the created_at date in the words table. I'm assuming that you have a field in your words table called word where you store the actual word.

    I'm also assuming that you might have multiple entries for the same word (possibly with different quantities) in the one day.

    So, this will give you an ordered hash of counts of words per day:

    project.words.group('DATE(created_at)').group('word').sum('quantity')
    

    If those guesses make no sense, then perhaps you can give a bit more detail about the structure of your models.