Output sum of decimal/float array rails - ruby-on-rails

I have the following which i thought would get me the sum of the array but doesnt:
<% #orders.each do |order| %>
<% if Product.exists?(sku: order.line_items.where().map {|li| li.sku }) %>
<%= order.line_items.where(vendor_name: #vendor.vendor_name).map do |li| %>
<% if Product.exists?(sku: li.sku) %>
<% product = Product.find_by(sku: li.sku ) %>
<% ((li.store_price.to_d * li.store_fulfillable_quantity) - (product.production_price * li.store_fulfillable_quantity)) * (0.70) %>
<% end %>
<% end.compact.sum %>
<% end %>
<% end %>
The output is something like:
25.21 25.21 12.66 5.33 12.66 9.01
I need to add these numbers. How can I do this with the decimals/floats?
When I use
<%= #orders.each do |order| %>
I get undefined method + for nilclass for the line that is on, and it's not nil but obviously I'm missing some factor on how sum works.

<%= #orders.map do |order| %>
<% if Product.exists?(sku: order.line_items.where().map {|li| li.sku }) %>
<% order.line_items.where(vendor_name: #vendor.vendor_name).map do |li| %>
<% if Product.exists?(sku: li.sku) %>
<% product = Product.find_by(sku: li.sku ) %>
<% ((li.store_price.to_d * li.store_fulfillable_quantity) - (product.production_price * li.store_fulfillable_quantity)) * (0.70) %>
<% end %>
<% end.compact.sum %>
<% end %>
<% end.compact.sum %>
Is how i got it to work

method reduce in arrays designed for getting reduced value of collection:
array.compact.reduce(:+)
# => Sum of array
more info about reduce

Related

There is a space between the elements rails?

As you can see below, I am having a problem of getting extra spaces in my search result. As you see in the photo, between the numbers and the elements, I am getting spaces and I do not why?
<td>
<% saved_element = ""%>
<% sensor.base_material.elests.each_with_index do |elest, v| %>
<% if elest.element.include? "O" %>
<% saved_element = elest %>
<% else %>
<%= elest.element.split('-').last %>
<% if elest.stoich != 1 %>
<sub><%= elest.stoich.to_i %></sub>
<% end %>
<% end %>
<% end %>
<% if saved_element.present? %>
<%= saved_element.element.split('-').last%>
<% if saved_element.stoich != 1 %>
<sub><%= saved_element.stoich.to_i %></sub>
<% end %>
<% end %>
</td>

How to get previous item in each loop

I have a SQL query that loads information into a hash. I want to iterate through that information and output it into the view.
If the user_id is the same as the previous object's user_id, I don't want to display that user_id, just the name and everything else. It seems like the logic should be simple, but being a novice at Ruby and Rails, I'm not sure what is really available to do this.
I was trying something like this, but prev_id was never getting updated after the first iteration:
<% #session.each_with_index do |s, x| %>
<% if x == 0 then prev_id = 'nil' end %>
<% curr_id = s['id'] %>
<% if curr_id != prev_id %>
<%= s['id'] %>
<% end %>
<%= s['name'] %>
<%= s['count'] %><br>
<% prev_id = curr_id %>
<% end %>
Any help is greatly appreciated!
You have to declare your prev_id outside of the loop for it to persist between iterations:
<% prev_id = nil %>
<% #session.each_with_index do |s, x| %>
<% if x == 0 then prev_id = 'nil' end %>
<% curr_id = s['id'] %>
<% if curr_id != prev_id %>
<%= s['id'] %>
<% end %>
<%= s['name'] %>
<%= s['count'] %><br>
<% prev_id = curr_id %>
<% end %>
You should use chunk.
<% #session.chunk{|s| s["id"]}.each do |curr_id, a| %>
<%= curr_id %>
<% a.each do |s| %>
<%= s["name"] %>
<%= s["count"] %><br>
<% end %>
<% end %>

undefined method `author' for nil:NilClass

I have some problems with my rails application.
<% #story.chapters.each do |chapter| %>
<% if round.to_s != chapter.round %>
<% if chosenChapterRound != chapter.round %>
<% maxVotes = 0 %>
<% end %>
<% if chapter.votes.count > maxVotes %>
<% maxVotes = chapter.votes.count %>
<% chosenChapterRound = chapter.round %>
<% chosenChapters[round.to_i] = chapter %>
<% end %>
<% end %>
<% end %>
<% chosenChapters.each do |chosenChapter| %>
<%= chosenChapter %>
<% end %>
this outputs something like this: #< Chapter:0x007fa1b8f59888>
What I really want to do is this:
<% chosenChapters.each do |chosenChapter| %>
<%= chosenChapter.author %>
<% end %>
But whenever I try to access one of the attributes inside of chosenChapter, I get a the following errormessage:
undefined method `author' for nil:NilClass
What am I doing wrong? Thanks!
At least one of your chosenChapters is nil. The problem is probably in the following fragment:
<% maxVotes = chapter.votes.count %>
<% chosenChapterRound = chapter.round %>
<% chosenChapters[round.to_i] = chapter %>

How to sum fields after group_by

I need to group some records by date, then sum one field for each of those days.
This is the code I'm trying to refactor:
<% #startdate.upto(#enddate) do |date| %>
<% visitors = #links.where("created_at >= ? AND created_at < ?", date, date+1).order("created_at ASC").select("id, visit_count") %>
<%= datevisitors.sum("visit_count") || 0 %>
<% end %>
I've started with:
<% visitors = #links.select("visit_count, created_at").group_by{|l| l.created_at.day} %>
<% #startdate.upto(#enddate) do |date| %>
<%= visitors[date] ...?
<% end %>
When you group_by something, you receive an array of the day and the element. So if you group by day, you'll have the Day and the elements that are part of the array:
<% #links.group_by{|l| l.created_at.day}.each do |day, links| %>
<p><%= day %>: <%= links.sum(&:visit_count) %></p>
<% end %>
EDIT --
OK, in that case your code looks like it was very close:
<% visitors = #links.select("visit_count, created_at").group_by{|l| l.created_at.day} %>
<% #startdate.upto(#enddate) do |date| %>
<% if visitors[date] %>
<%= visitors[date].sum(&:visit_count) %>
<% else %>
0
<% end %>
<% end %>
It's probably better to move this to a helper (or presenter)
def daily_visits(links, from, to)
links_by_day = links.select("visit_count, created_at").group_by{|l| l.created_at.day}
range = from.upto(to).to_a
range.inject({}) do |date, hash|
hash[date] = links_by_day.fetch(date, 0)
end
end
Then, in the view:
<% daily_visits(#links, #startdate, #enddate).each do |day, count| %>
<%= day %>: <%= count %>
<% end %>
This should be on controller
#dates_with_visitors = #links.select("visit_count, created_at").group_by(&:created_at)
This should be on the view
<% #dates_with_visitors.each do |date_with_visitors| %>
<%= "#{date_with_visitor[0]} - Visits: #{date_with_visitors[1].sum(&:visit_count)}" %>
<% end %>
Hi can you give me the Model that will be used?
Here's my example on a Activerecord with a aggregate sum function:
<% #sum_visit_count = Visitor.find(:all, :select => "SUM(visit_count)", :group => "id, date_visit") %>
and
<%= #sum_visit_count.sum %>

Rails element if first time appearance

I have a model Post with :mark, :text
I have a list with my post
<% #posts.each do |p| %>
# todo
<% if p.mark? %>
<%= p.mark %> <%= sweet_thing(p.text) %>
<% else %>
<%= sweet_thing(p.text) %>
<% end %>
<% end %>
I need to show p.mark name instead #todo where p.mark first time appearance.
Final txt example:
Audi
Audi, text-text-text-text.
Audi, text-text-text-text.
Audi, text-text-text-text.
Ford
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
UPDATE
My txt render in controller
def txt_receiver
#posts = Post.where("created_at >= ?", 7.days.ago.utc).find(:all, order: "mark, LOWER(post)")
render "txt_for_newspapper", formats: ["text"]
end
An obvious solution is to keep track of seen marks.
<% seen_marks = {} %>
<% #posts.each do |p| %>
<% unless seen_marks[p.mark] %>
<%= p.mark %>
<% seen_marks[p.mark] = true %>
<% end %>
# rest of your code
<% end %>
A better solution (I think) involves grouping posts by their mark and then outputting in groups. But I'm not sure whether it will match your logic regarding missing marks.
<% #posts.group_by(&:mark).each do |mark, posts| %>
<%= mark %>
<% posts.each do |p| %>
<%= p.mark if mark %> <%= sweet_thing(p.text) %>
<% end %>
<% end %>

Resources