Я новичок в программировании, но вот в чем дело: я пытаюсь создать приложение для рельсов, которое берет данные из базы данных postgresql и показывает сводку в диаграмме jqPlot, но у меня проблемы с моими запросами. Мне нужен массив для диаграммы, который будет отформатирован примерно так: total_durations=[["Jan", 3456],["Feb", 21] и т. д.]
Вот таблица usagedata в моей базе данных:
╔═══════════════╦═════════════╦═════════════════════╦════════════════╗
║ record_id ║ user_id ║ submit_time ║ duration ║
╠═══════════════╬═════════════╬═════════════════════╬════════════════╣
║ 1 ║ 6 ║ 2012-09-19 22:18:58 ║ 45 ║
║ 2 ║ 1 ║ 2012-09-19 22:45:59 ║ 0 ║
║ 3 ║ 5 ║ 2012-09-20 01:57:52 ║ 3987 ║
║ 4 ║ 8 ║ 2012-09-18 03:47:53 ║ 34 ║
║ 5 ║ 9 ║ 2013-01-26 20:38:03 ║ 678 ║
║ 6 ║ 1 ║ 2013-01-26 23:41:44 ║ 56 ║
║ 7 ║ 2 ║ 2013-01-27 02:10:41 ║ 100 ║
╚═══════════════╩═════════════╩═════════════════════╩════════════════╝
<сильный>1. Частичный метод
У меня есть Model Usagedata.rb:
class Usagedata < ActiveRecord::Base
def self.by_month
h = Usagedata.calculate(:sum, :duration, :conditions => {
:submit_time => (Time.now.all_year) },
:order => "EXTRACT(month FROM submit_time)",
:group => ["EXTRACT(month FROM submit_time)","EXTRACT(year FROM submit_time)"])
end
end
использование контроллераdata_controller.rb:
class UsagedataController < ApplicationController
def index
end
private
def set_usagedata
@usagedata = Usagedata.find(params[:id])
end
def usagedata_params
params[:usagedata]
end
end
И просмотрите index.html.haml:
%br=h = Usagedata.by_month
Вывод представления:
{[1.0, 2013.0]=>135776897, [2.0, 2013.0]=>100620585, [3.0, 2013.0]=>162980319, [4.0, 2013.0]=>26916589, [5.0, 2013.0]=>18793323, [6.0, 2013.0]=>9250440, [7.0, 2013.0]=>5011563, [12.0, 2012.0]=>24092}
Как я могу получить массив total_durations=[["Jan", 3456],["Feb", 21], etc]
в соответствии с таблицей базы данных, где месяц берется из поля submit_time, а другое число представляет собой сумму длительностей, сделанных каждый месяц. Или даже массив типа total_durations=[["1.0, 2013.0", 135776897],["2.0, 2013.0", 100620585], etc]
поможет.
<сильный>2. Частичный метод
Мне удалось получить то, что мне нужно, в БД:
select to_char(submit_time,'Mon') as mon,
extract(year from submit_time) as yyyy,
sum("duration") as "Total_Duration"
from usagedata
group by 1,2
но как я могу получить вывод запроса в массив в Rails?
Я пробовал это на своей странице html.haml:
%br=Usagedata.select("duration, extract (month from submit_time) as month, extract(year from submit_time) as year, SUM(submit_time) as total").group(1,2)
Но это просто строка печати:
#<ActiveRecord::Relation::ActiveRecord_Relation_Usagedata:0x007f1c10997518>
Также попытался добавить его в свой контроллер как:
@fetch = []
Usagedata.select("extract (month from submit_time) as month, extract(year from submit_time) as year, SUM(duration)").group_by(1,2).each do |ph|
@fetch << [ph.month.to_f, ph.year, ph.sum]
end
Но это просто дает мне ошибку:
PG::Error: ERROR: column "usagedata.submit_time" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT extract (month from submit_time) as month, extract(ye... ^ : SELECT extract (month from submit_time) as month, extract(year from submit_time) as year, SUM(duration) FROM "usagedata"
<сильный>3. Частичный метод
Описан здесь: http://railsforum.com/viewtopic.php?id=27205
controller.rb:
@usagedata_groups = Usagedata.find(:all,
:select => 'submit_time, wall_duration, id',
:conditions => {:machine_name_id => ["1"]},).group_by{|usagedata| usagedata.submit_time.beginning_of_month}
@fetch = []
Usagedata.find(:all,
:select => 'submit_time, wall_duration, id',
:conditions => {:machine_name_id => ["1"]},).group_by{|usagedata| usagedata.submit_time.beginning_of_month}.keys.sort.each do |month|
@fetch << month.strftime("%B %Y")
@fetch << month.collect(&:wall_duration).sum
end
index.html.haml
%table
%tr
%th
- @usagedata_groups.keys.sort.each do |month|
%tr
%td
#{month.strftime("%B %Y")}
%td
#month.collect(&:wall_duration).sum
%table
%tr
%th Show @fetch content:
- @fetch.each do |co|
%tr
%td=co
Вывод без строки @fetch << month.collect(&:wall_duration).sum
в контроллере:
February 2013 98503443
March 2013 162980319
April 2013 26916589
May 2013 18793323
June 2013 9250440
July 2013 5399525
Show @fetch content
February 2013
March 2013
April 2013
May 2013
June 2013
July 2013
с этой строкой я получаю сообщение об ошибке:
NoMethodError in UsagedataController#index
undefined method `collect' for Fri, 01 Feb 2013 00:00:00 UTC +00:00:Time
Пожалуйста помоги!
{[1.0, 2013.0]=>135776897, [2.0, 2013.0]=>100620585, [3.0, 2013.0]=>162980319, [4.0, 2013.0]=>26916589, [5.0, 2013.0]=>18793323, [6.0, 2013.0]=>9250440, [7.0, 2013.0]=>5011563, [12.0, 2012.0]=>24092}
Вы можете сделать:{[1.0, 2013.0]=>135776897, [2.0, 2013.0]=>100620585, [3.0, 2013.0]=>162980319, [4.0, 2013.0]=>26916589, [5.0, 2013.0]=>18793323, [6.0, 2013.0]=>9250440, [7.0, 2013.0]=>5011563, [12.0, 2012.0]=>24092}.map{ |k,v| [k.join(', '), v] }
что должно дать желаемый результат. - person Surya   schedule 27.12.2013