使用PostgreSQL for Rails生成JSON响应

时间:2016-06-21 17:37:15

标签: ruby-on-rails json postgresql

我目前正在Rails中执行一个SQL语句,当它工作时我已经意识到我需要一种不同的格式并试图在PostreSQL中实现这一点。这是我的问题:

    sql = "SELECT one_month_high - one_month_low as one_month,
          three_month_high - three_month_low as three_month,
          six_month_high - six_month_low as six_month,
          twelve_month_high - twelve_month_low as twelve_month,
          ytd_high - ytd_low as ytd,
          saved_on
          FROM daily_high_lows
          ORDER BY saved_on DESC;"

返回:

#<PG::Result:0x007fdb4aea1fa0 status=PGRES_TUPLES_OK ntuples=380 nfields=6 cmd_tuples=380>
...
{"one_month"=>"544", "three_month"=>"214", "six_month"=>"9","twelve_month"=>"122",
"ytd"=>"143", "saved_on"=>"2016-06-09 00:00:00"}
{"one_month"=>"1283", "three_month"=>"475", "six_month"=>"22","twelve_month"=>"189",
"ytd"=>"517", "saved_on"=>"2016-06-08 00:00:00"}

我已经意识到我需要一种格式:

[
  {
    name: "One Month",
    data: {
      2016-06-09 00:00:00: 544,
      2016-06-08 00:00:00: 1283
    }
  },
  {
    name: "Three Month",
    data: {
     2016-06-09 00:00:00: 214,
     2016-06-08 00:00:00: 475
    }
  }, etc...
] 

我一直在努力研究如何做到这一点,但目前它有点超出我的范围,所以我可以使用一些方向。

2 个答案:

答案 0 :(得分:0)

您应该能够使用rails中提供的to_json方法。所以response.to_json应该产生你需要的东西。

答案 1 :(得分:0)

我认为如果你有很多记录,在Postgres中构建JSON是一个很好的方法。 Postgres在9.4之前并没有真正获得非常有用的JSON构建功能,所以我建议你至少在那里,如果不是更高。无论如何,这似乎给你你想要的东西:

WITH seqs AS (
  SELECT  json_object_agg(saved_on::text, one_month_high ORDER BY saved_on) one_month_highs,
          json_object_agg(saved_on::text, one_month_low ORDER BY saved_on) one_month_lows
  FROM    daily_high_lows
)
SELECT  json_agg(j)
FROM    (
  SELECT json_build_object('name', 'One Month Highs', 'data', one_month_highs)
  FROM   seqs
  UNION ALL
  SELECT json_build_object('name', 'One Month Lows', 'data', one_month_lows)
  FROM seqs
) x(j)
;

如此测试:

t=# create table daily_high_lows (one_month_high integer, one_month_low integer, three_month_high integer, three_month_low integer, six_month_high integer, six_month_low integer, twleve_month_high integer, twelve_month_low integer, ytd_high integer, ytd_low integer, saved_on timestamp);
t=# insert into daily_high_lows (one_month_high, one_month_low, three_month_high, three_month_low, saved_on) values (1, 10, 3, 6, '2016-06-08');
t=# insert into daily_high_lows (one_month_high, one_month_low, three_month_high, three_month_low, saved_on) values (2, 9, 3, 8, '2016-03-09');
t=# with seqs as (select json_object_agg(saved_on::text, one_month_high order by saved_on) one_month_highs, json_object_agg(saved_on::text, one_month_low order by saved_on) one_month_lows from daily_high_lows) select json_agg(j) from (select json_build_object('name', 'One Month Highs', 'data', one_month_highs) from seqs union all select json_build_object('name', 'One Month Lows', 'data', one_month_lows) from seqs) x(j);
                                                                                              json_agg                                                                                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [{"name" : "One Month Highs", "data" : { "2016-03-09 00:00:00" : 2, "2016-06-08 00:00:00" : 1 }}, {"name" : "One Month Lows", "data" : { "2016-03-09 00:00:00" : 9, "2016-06-08 00:00:00" : 10 }}]
(1 row)