Rails无法正确显示来自Postgres JSON函数的嵌套JSON结果

问题描述 投票:2回答:2

出于各种原因,我正在创建一个应用程序,该应用程序将SQL查询字符串作为URL参数,并将其传递给Postgres(类似于CartDB SQL API和CFPB的Qu)。然后,Rails呈现来自Postgres的结果的JSON响应。

我的控制器中的代码段:

@table = ActiveRecord::Base.connection.execute(@query)
render json: @table

这很好。但是,当我使用Postgres JSON函数(row_to_json,json_agg)时,它将嵌套的JSON属性呈现为字符串。例如,以下查询:

query?q=SELECT max(municipal) AS series, json_agg(row_to_json((SELECT r FROM (SELECT sch_yr,grade_1 AS value ) r WHERE grade_1 IS NOT NULL))ORDER BY sch_yr ASC) AS values FROM ed_enroll WHERE grade_1 IS NOT NULL GROUP BY municipal

返回:

{
series: "Abington",
values: "[{"sch_yr":"2005-06","value":180}, {"sch_yr":"2005-06","value":180}, {"sch_yr":"2006-07","value":198}, {"sch_yr":"2006-07","value":198}, {"sch_yr":"2007-08","value":158}, {"sch_yr":"2007-08","value":158}, {"sch_yr":"2008-09","value":167}, {"sch_yr":"2008-09","value":167}, {"sch_yr":"2009-10","value":170}, {"sch_yr":"2009-10","value":170}, {"sch_yr":"2010-11","value":153}, {"sch_yr":"2010-11","value":153}, {"sch_yr":"2011-12","value":167}, {"sch_yr":"2011-12","value":167}]"
},
{
series: "Acton",
values: "[{"sch_yr":"2005-06","value":353}, {"sch_yr":"2005-06","value":353}, {"sch_yr":"2006-07","value":316}, {"sch_yr":"2006-07","value":316}, {"sch_yr":"2007-08","value":323}, {"sch_yr":"2007-08","value":323}, {"sch_yr":"2008-09","value":327}, {"sch_yr":"2008-09","value":327}, {"sch_yr":"2009-10","value":336}, {"sch_yr":"2009-10","value":336}, {"sch_yr":"2010-11","value":351}, {"sch_yr":"2010-11","value":351}, {"sch_yr":"2011-12","value":341}, {"sch_yr":"2011-12","value":341}]"
}

因此,它仅部分呈现JSON,当我在查询中嵌套使用Postgres函数创建的JSON数组时,就会遇到问题。

我不确定从哪里开始这个问题。有任何想法吗?我确信这是Rails的问题。

ruby-on-rails json postgresql
2个回答
1
投票

ActiveRecord::Base.connection.execute不知道如何将数据库类型分解为Ruby类型,因此从中得到的所有内容(数字,布尔值,JSON,所有内容)都是字符串。如果您想从控制器中获取明智的JSON,则必须手动将@table中的数据转换为Ruby类型,然后以常规方式将Ruby格式的数据转换为JSON。

您的@table实际上将是PG::Result实例,并且这些实例具有诸如PG::Result(获取列类型)和ftype(获取列的类型修饰符)之类的方法,可以帮助您确定哪种排序方式数据位于ftype的每一列中。您可能会要求fmod作为每一列的类型和修饰符,然后将它们交给fmod PostgreSQL函数以获得一些可理解的类型字符串。然后将这些类型的字符串映射到转换方法,然后使用该映射来解包返回的字符串。如果深入研究ActiveRecord源,您将看到AR做类似的事情。虽然AR源代码不适合胆怯的人,对不起,但是当您走出应如何与数据库进行AR事物的狭窄界限时,这是正确的做法。

[您可能想重新考虑一下“ SQL的笨拙”方法。如果您能找到一种自己构建SQL的方法,则可能会更轻松(并且在查询时可以将其列入白名单)。


0
投票

PG::Result类(@table的类型),利用PG::Result将结果值类型转换为红宝石对象。对于您的示例,可以如下使用format_type

format_type
© www.soinside.com 2019 - 2024. All rights reserved.