counting values in embedded ruby - ruby-on-rails

Quick fire question.
If I have a list of values and I wan't to find the total and display it in embedded ruby, how would I go about this.
<% #user.recipes.each do |i| %>
<% i.awards.each do |k| %>
<%= k.points %>
<% end %>
<% end %>
This renders:
1 10 5 5 10 1 5 10 5 1
with each number (1, 5 or 10) being a value from the database. Is there any way to get a count of this? Or would it be better to create a seperate method in the controller to work this out?

<%= i.awards.sum(:points) %>
For for the sum of all points from all recipes:
<%= #user.recipes.map { |r| r.awards.sum(:points) }.sum %>
Although it might be sensible to do this calculation within the model. You'll remove a lot of duplication that way if you use it in more than one view.
UPDATE:
As per the comments below, you could also ask the DB to calculate the sum for you:
<%= #user.recipes.joins(:awards).sum('awards.points') %>

Related

Inserting something in between every 3 topics at `<%= render #topics %>`?

I'm trying to insert some images in between my topics (one in between every 3 topics for the first 3 groups of topics -- ie. 3 images in total), but I'm confused as to where since my forums/show.html.erb only has <%= render #topics %> and not some sort of each loop that I could manipulate.
If you are not looking for a very fancy ruby way to do it, just do it the dirty way:
<% #topics.each_with_index do |topic, index| %>
<% if index != 0 && index%3==0 %>
<%= render #ad %>
<% end %>
<%= render topic %>
<% end %>
or if your partial takes the entire array do that in your partial logic. However if you want a fancy way, this solution will help you: New row every 3 items

Ruby on Rails, Using sort on each do

I'm trying to use sort on each do. I get the error
wrong number of arguments(1 for 0)
I understand that I cannot daisy chain them together. Does anyone know another methods of getting this done.
<% Category.sort(:id).limit(4).each do |type| %>
<%= type.name %>
<% end %>
The result I am aiming for is to have all categories listed from a to z.
Assuming the Category is an Active Record then
<% Category.order(:id).limit(4).each do |type| %> would do the trick.

Rails creating multidimensional array within loop

I'm trying to loop through an array of the next 7 days, and for each, perform a query to find all the 'Time slots' that match, and add these to an object which I can loop through in my view. This is fairly simple in PHP, but I'm not sure of the syntax in rails. I have a situation where each day can have multiple 'delivery slots' available, and I need to display all these slots for the next week, by day.
So far in my controller I have
d = Date.today
d2 = d + 1.week
#days = (d..d2).to_a
#deliveries = []
#days.each do |d|
#deliveries[][dayname] = d.strftime("%a")
#deliveries[][slots] = Model.where("day = ?", d.strftime("%w"))
end
Then in my view, I want to do this
<% #deliveries.each do |d| %>
<%= d.dayname %>
<% d.slots.each do |s| %>
<%= slot data here %>
<% end %>
<% end %>
Where am I going wrong? Not quite sure of the syntax in rails where you'd use "as key => value" in php. Is this the most efficient way to go about it? It will result in 7 queries which isn't ideal
Thanks for any help
If your Model only has a day number, the slots will be the same for every week and you could do something like:
slots_by_day = Model.all.group_by(&:day)
#deliveries = (Date.today..Date.today + 6.days).each_with_object({}) do |day, dayname_groups|
dayname_groups.merge!(day.strftime('%a') => slots_by_day[day.strftime('%w').to_i])
end
It will fetch all models, group them by day number of the week and then build a hash mapping each day number with the day name ending up in a hash like:
=> {"Wed"=>[#<Model...>, #<Model...>, #<Model...>, #<Model...>],
"Thu"=>[#<Model...>, #<Model...>, #<Model...>, #<Model...>], "Fri"=>...}
The hash would be used like this:
<% #deliveries.each do |dayname, slots| %>
<%= dayname %>
<% slots.each do |s| %>
<%= slot data here %>
<% end %>
<% end %>

Ruby: totalling amounts

I have a Donation.rb model with an amount column that takes an integer. I want to sum all the individual donations together and show the total on the home page.
In the home_controller, I'm doing #donations = Donation.all and then in the view I do
<% sum = 0 %>
<% #donations.each do |donation| %>
<%= sum += donation.amount if donation.amount? %>
<% end %>
The problem is that this is printing the running sum each time a new donation is added to it. I just want the total sum at the end after they've all been added together.
You shouldn't be doing any calculations in the view, this stuff should be done in the controller or model if it can be. For something like this I'd do in the controller
#donations = Donation.paginate(:page => params[:page], :order => 'created_at desc', :per_page => 20)
#sum = Donation.sum(&:amount)
Then simply print out the #sum in the view
<%= #sum %>
You're getting running sum printed, because you're actually printing it with the = sign.
You need to change this line:
<%= sum += donation.amount if donation.amount? %>
With:
<% sum += donation.amount if donation.amount? %>
And then, just print the value of sum wherever you want doing:
<%= sum %>
This should print the sum once its done calculating.
<% sum = 0 %>
<% #donations.each do |donation| %>
<% sum += donation.amount if donation.amount? %>
<% end %>
<%= sum %>
It's because any instance of <%= ... %> will inline the result. The regular <% ... %> version will not.
Don't do this kind of computation in the view, though. Make a class method on Donation which will handle it for you. If you need more than one line to express a computation in a view, make a helper method, or better, a model method.

Rails each loop insert tag every 6 items?

I have X number of image objects that I need to loop through in a view and want to create a new div every 6 objects or so (for a gallery).
I have looked at cycle but it seems to change every other record. Does anyone know of a way to insert code into a view every 6 times?
I could probably do it with nested loops but I am kinda stumped on this one.
You can use Enumerable#each_slice in conjunction with #each to avoid inline calculations. each_slice breaks the array into chunks of n, in this case 6.
<% #images.each_slice(6) do |slice| -%>
<div class="gallery">
<% slice.each do |image| -%>
<%= image_tag(image.url, :alt => image.alt) %>
<% end -%>
</div>
<% end -%>
This is a Ruby question. You can meld this into whatever your view is trying to do.
#list.each_with_index do |item, idx|
if((idx + 1) % 6 == 0)
# Poop out the div
end
# Do whatever needs to be done on each iteration here.
end

Resources