Asciant
Asciant

Reputation: 2160

Rails loop refactor

I have created a loop, to calculate a total rating of a record. To do this I am first looping through all the child records (ratings), extracting the rating from each row, adding it to the total and then outputting the total.

<% total = 0 %>
<% for ratings in @post.ratings %>
    <% total = (total + ratings.rating) %>
<% end %>
<%= total %>

My question is, simply, Is this the rails way?

It achieves the desired result, although needs 5 lines to do so. I am worried I am bring old habits from other languages into my rails project, and I am hoping someone could clarify if there is an easier way.

Upvotes: 1

Views: 95

Answers (3)

Jeff Doyle
Jeff Doyle

Reputation: 71

The following, preferably in the controller, will do it succinctly:

@rating = @post.ratings.sum { &:rating }

If that seems cryptic, you might prefer

@rating = @post.ratings.inject(0) { |sum, p| sum + p.rating }

Note, however, that this will fail if any of the ratings are null, so you might want:

@rating = @post.ratings.inject(0) { |sum, p| sum + (p.rating || 0) }

Upvotes: 3

mind.blank
mind.blank

Reputation: 4880

Put the following in your controller, then you just need to use @rating in your view:

total = 0
@rating = @post.ratings.each { |r| total += r.rating }

Or you could move it into the Post model and do something like:

def self.total_rating
  total = 0
  ratings.each { |r| total += r.rating }
  total
end

and then simply call @post.total_rating

Upvotes: 0

Oleksi
Oleksi

Reputation: 13097

You should generally keep logic out of your views. I would put that code in a helper or a controller, and the call a method to calculate the total

Upvotes: 1

Related Questions