Ruby generate table from date range - ruby-on-rails

I've been having a lot of trouble with this:
For an RPI application, all my results are within one table: results
I'm trying to print a table based on a specific data range: 2011-07-31..2012-07-01
In my controller:
class SeasonsController < ApplicationController
def s2012
#results = Result.all
#s2012 = Result.where(:date => (2011-07-31)..(2012-07-01))
end
end
In my view:
<table>
<tr>
<th>Event ID</th>
<th>Date</th>
</tr>
<% #s2012.each do |result| %>
<tr>
<td><%= result.event_id %></td>
<td><%= result.date %></td>
</tr>
<% end %>
</table>
This doesn't output any errors (small miracle), but nothing is displayed in the view. #results = Result.all prints all the whole table just fine. But how can I limit it to a specific data range?

I know you're trying to do this all ActiveRecordy, but imo it's actually less readable than if you just wrote the SQL where clause yourself.
Result.where('date BETWEEN ? AND ?',
Date.parse('2011-07-31'),
Date.parse('2012-07-01'))

maybe try:
Date.parse('2011-07-31')..Date.parse('2012-07-01')

In your current example rails will think you are doing arithmetic. You are looking at a date between the number 1973 and 2004. Instead you want to convert them to date objects first. Do
#s2012 = Result.where(:date => DateTime.parse('2011-07-31')..DateTime.parse('2012-07-01'))

Related

Print hash on table html - Ruby on rails

I have an instance variable #report_antennas_control_access with this data
[{:id_control_access=>1, :input=>"Antena 1"}, {:id_control_access=>1, :output=>"Antena 2"}, {:id_control_access=>1, :input=>"Antena 5"}, {:id_control_access=>2, :input=>"Antena 3"}, {:id_control_access=>2, :output=>"Antena 4"}] and I want to print it in my .html table but in doing so I do it in a way that I do not want
I do it this way:
<tbody>
<% #report_antennas_control_access.each do | antennas | %>
<tr>
<% if control_access[:id_control_access] == antennas[:id_control_access] %>
<td><%= antennas[:input] %></td>
<td><%= antennas[:output] %></td>
<% end %>
</tr>
<% end %>
</tbody>
But he prints it to me in a way I do not want:
This is the way I need to print that data (example):
As David already said, with your input, it will be really difficult to achieve what you need. Since it was fun, I fixed it, but I do believe that it should be fixed somewhere higher in your code (I hope you're using Ruby 2.5+, if not, let me know which version you are on).
def fix_my_data(data)
data.group_by { |x| x[:id_control_access] }
.transform_values do |v|
v.map { |h| h.slice(:input, :output) }
.group_by { |h| h.keys.first }.values.inject(:zip).map { |x,y| x.merge(y.to_h) }
end
end
If you pass your array into this function, it will return this:
{1=>[{:input=>"Antena 1", :output=>"Antena 2"}, {:input=>"Antena 5"}],
2=>[{:input=>"Antena 3", :output=>"Antena 4"}]}
Which should be really simple to generate HTML with, like so:
<tr>
<% #data[control_access[:id_control_access]].each do |antenna| %>
<td><%= antenna[:input] %></td>
<td><%= antenna[:output] %></td>
<% end %>
</tr>
I'm pretty sure fix_my_data can be written in a bit simpler way, but as I mentioned, it's a late place to be fixing the data.
The problem is that you are iterating over each hash and trying to access data in either the hash before or after. Take the first hash for example: {:id_control_access=>1, :input=>"Antena 1"}. You call antennas[:input] on it, so it displays "Antena 1". But then you call antennas[:output], and there is no output key in the current hash, so it's returning nil and causing the corresponding table cell to be blank.
You should consider updating the structure of your hashes, if you can, so that they look like {:id_control_access=>1, :input=>"Antena 1", :output=>"Antena 2"}. It seems to me to make more logical sense, and would solve the problem with your table.

Average values by group

I have two tables in my web app: one is for Donors (called "donors") and the other is for Donation Amounts (called "donations). When you click on a donor, you can see all of their donations.
I'm trying to average values associated with a particular date, for a particular charity. For example, if these records exist for Donor A:
*Donor A*
Date Donation Amount
05/04/2013 30
05/04/2013 40
05/05/2013 15
05/05/2013 75
I'd like the system to also calculate and display that the average donation amount for 05/04/2013 was 35 and the average donation amount for 05/05/2013 was 45.
Currently I've tried using the group attribute in my donor model:
def self.average_donateperdate
Donation.average(:donateamount, conditions: ["donor_id = ?", #donor], group: "donatedate")
end
This doesn't seem to work. Since I'm new to Rails, I'm not entirely sure whether this is the right way to do it or not. There are a few other posts that touch on this topic, but none that have helped me solve the issue. Any help would be greatly appreciated!
The simplest syntax to do this is:
#donor.donations.group(:donatedate).average(:donateamount)
This will return a hash in the format { 'donatedate' => 'average donateamount' }.
Naturally, this assumes you have a has_many :donations association on your Donor model. A reusable method would look like:
def average_donation_by_date
donations.group(:donatedate).average(:donateamount)
end
And you can now simply call:
#donor.average_donation_by_date
To see this visually, you can call this in your controller:
#average_donations = #donor.average_donation_by_date.to_a.sort_by(&:first)
And your view might contain something like this:
<table>
<thead>
<tr>
<th>Date</th>
<th>Average Donation</th>
</tr>
</thead>
<tbody>
<% #average_donations.each do |date, amount| %>
<tr>
<td><%= date.strftime('MM/dd/yyyy') %></td>
<td><%= amount %></td>
</tr>
<% end %>
</tbody>
</table>
Reference
Rails api - calculate grouped values

Sorting my Rails Table

My controller:
def index
#unique_bug = Rating.find_by_sql("SELECT bug FROM ratings WHERE bug <> '' GROUP BY bug")
end
Rating Model:
def self.metrics_bug_count(bug)
count = where(bug:"#{bug}").count
total = Rating.find_by_sql("SELECT bug FROM ratings WHERE bug <> ''").count
percentage = (count.to_f/total.to_f * 100)
return count, percentage
end
My view:
<table class="table table-bordered">
<tr>
<th><h3>Bug</h3></th>
<th><h3>Total Occurrences</h3></th>
<th><h3>Frequency</h3></th>
</tr>
<tr>
<%#unique_bug.each do |rating| %>
<% count, percentage = Rating.metrics_bug_count(rating.bug)%>
<td><p class="text-center"><h4><%= rating.bug.capitalize %></h4></p></td>
<td><p class="text-center"><h4><%= count %></h4></p></td>
<td><p class="text-center"><h4><%= number_to_percentage(percentage, :precision => 2)%></h4></p></td>
</tr>
<%end%>
</table>
How can I make each row (Bug, Total, Frequency) to each be sortable? I watch the Railscast episode on sortable tables, however the sorting there is done in the controller. How can I sort my table with a more complex find that is being performed in my model.
you can use .order
For example, Rating.order("count DESC").
Besides, I think you can avoid using find_by_mysql and use some rails method to do your query which is more readable and easier.
You can get the unique 1 using .uniq as well.
try have a look at
http://guides.rubyonrails.org/active_record_querying.html

Why is my Ruby On Rails database query so slow?

The following code always uses more then ten seconds. I have upgraded the server, but it doesn't help. I know I have some database design problems, but I can't modify that.
I am showing all the prices from differents locations of products of a category also in different time range, because the prices change every 15 days in each location.
controller
def prods_x_cat
# This will load all the products of a category
#products = Product.prods_x_cat(params[:id],:include => :raw_datas)
#cortes = RawData.cortes
respond_to do |format|
format.js { render :layout=>false}
end
end
prods_x_cat.js.erb
var jqxhr1 = $.ajax($("#loading_overlay .loading_message, #loading_overlay").fadeIn());
$('#datos').html("<%= escape_javascript render :partial=>'/shared/prods_x_cat'%>")
view
<%#cortes.each do |c|%>
<%=c.corte%>
<%end%>
<%#cortes.each do |c|%>
<%#fecha = c.corte_real%>
<div id="<%=c.corte%>" class="block no_padding">
<table class="display datatable">
<thead>
<tr>
<th>SKU</th>
<%Company.active.order('table_field ASC').each do |c|%>
<th><%=c.abbr%></th>
<%end%>
<th>Average</th>
<th>Mode</th>
<th>Minimum</th>
<th>Maximum</th>
</tr>
</thead>
<tbody>
<%#products.each do |p|%>
<tr class="gradeA">
<td><%=p.name%></td>
<%p.raw_datas.where("product_id='#{p.id}' and corte_real='#{#fecha}'").each do |prd|%>
<td><%=prd.location1.to_f.round(2)%></td>
<td><%=prd.location2.to_f.round(2)%></td>
<td><%=prd.location3.to_f.round(2)%></td>
<td><%=prd.location4.to_f.round(2)%></td>
<td><%=prd.location5.to_f.round(2)%></td>
<td><%=prd.location6.to_f.round(2)%></td>
<td><%=prd.location7.to_f.round(2)%></td>
<td><%=prd.location8.to_f.round(2)%></td>
<td><%=prd.promedio.to_f.round(2)%></td>
<td><%=prd.moda%></td>
<td><%=prd.minimo.to_f.round(2)%></td>
<td><%=prd.maximo.to_f.round(2)%></td>
<%end%>
</tr>
<%end%>
</tbody>
</table>
</div>
<%end%>
</div>
This kind of question is pretty much impossible to answer without seeing all the code involved. Instead I can help you try to figure out where the problem is.
There are good tools for finding where your performance problems are (e.g. ruby-prof) but if you want a quick primitive way to find where your issue is, just use Time.now. For example, you could change your controller action to be:
def prods_x_cat
# This will load all the products of a category
a1 = Time.now
#products = Product.prods_x_cat(params[:id],:include => :raw_datas)
b1 = Time.now
p "Time for finding products: #{b1 - a1}"
a2 = Time.now
#cortes = RawData.cortes
b2 = Time.now
p "Time for finding cortes: #{b2 - a2}"
respond_to do |format|
format.js { render :layout=>false}
end
end
If the printouts suggest that the time is taken up elsewhere, start doing something similar in your template. Focus on the database calls.

Undefined Method, across classes, for a database derived field

I'm aware that variants of this question have been asked before, but I do believe my question is different ;-)
I have 2 Ruby on Rails classes (with assoc. controllers, models, etc). These are Devices and Messages.
In the Devices index.html view, I need to make reference to the newest Message record.
<table>
<tr>
<th>Device Name</th>
<th>Checked</th>
</tr>
<% newestMessage = Message.find(:all, :order => "updated_at DESC", :limit => 1) %>
<% #devices.each do |device| %>
<tr>
<td><%= device.name %></td>
<td><%= newestMessage.updated_at %></td>
</tr>
<% end %>
</table>
(I believe I should move the logic to a helper, but for the time being I'm keeping it as simple as possible while I get it working)
When I access this blahblah.com/devices, I get...
undefined method `updated_at' for #<Array:0x103f36c00>
Due to the line,
<td><%= newestMessage.updated_at %></td>
Now, I've seen questions like this that suggest to add the equivalent of the following to messages_controller.rb,
attr_accessor :updated_at
However, I've tried this and it doesn't help. Also, I don't think this should be necessary anyway as 'updated_at' is derived from the database, built with scaffold, etc.
If I just print 'newestMessage' it seems to have a sensible value.
My question is, how should I access fields within newestMessage, which are of class Message from the Device index.html.erb?
Thanks in advance.
Try newestMessage = Message.last then newestMessage.updated_at

Resources