How to calculate specific rating count hash in ruby on rails?

458 views Asked by At

So, I have an after_save hook on review model which calls calculate_specific_rating function of product model. The function goes like this:

def calculate_specific_rating
    ratings = reviews.reload.all.pluck(:rating)
    specific_rating = Hash.new(0)
    ratings.each { |rating| specific_rating[rating] += 1 }
    self.specific_rating = specific_rating
    save
  end

Right now, it returns

specific_rating => { 
"2"=> 3, "4"=> 1
}

I want it to return like:

specific_rating => { 
"1"=> 0, "2"=>3, "3"=>0, "4"=>1, "5"=>0
}

Also, is it okay to initialize a new hash everytime a review is saved? I want some alternative. Thanks

2

There are 2 answers

2
Sebastián Palma On BEST ANSWER

You can create a range from 1 until the maximum value in ratings plus 1 and start iterating through it, yielding an array where the first element is the current one, and the second element is the total of times the current element is present in ratings. After everything the result is converted to a hash:

self.specific_rating = (1..ratings.max + 1).to_h { |e| [e.to_s, ratings.count(e)] }
save
0
Gautam On

You could also do something like this -

def calculate_specific_rating
  ratings = [1,2,3,4,5]
  existing_ratings = reviews.group_by(&:rating).map{|k,v| [k, v.count]}.to_h
  Hash[(ratings - existing_ratings.keys).map {|x| [x, 0]}].merge(existing_ratings)
end

which gives

{3=>0, 4=>0, 5=>0, 2=>3, 1=>1}