ActiveRecord数组:: Base.connection.execute Ruby On Rails

时间:2012-12-03 03:22:55

标签: ruby-on-rails arrays postgresql activerecord

我是rails的新手,我需要执行一些sql查询并将数组输出到视图中。

在conttroler上

@accounts = Account.all
 @itemlist = Account.find(:all,:select => 'subdomain')

 @schemasize = ActiveRecord::Base.connection.select_rows(%q{select pg_size_pretty(CAST((SELECT SUM(pg_total_relation_size(table_schema || '.' || table_name) ) FROM information_schema.tables WHERE table_schema = '}+@itemlist.map(&:subdomain).join(" ")+%q{') As bigint) )  As schema_size}).to_s.gsub(/\D/, '').to_f / 1024

输出命令

  Account Load (36.0ms)  SELECT "public"."accounts".* FROM "public"."accounts"
  Account Load (2.0ms)  SELECT subdomain FROM "public"."accounts"
   (88.0ms)  select pg_size_pretty(CAST((SELECT SUM(pg_total_relation_size(table
_schema || '.' || table_name) ) FROM information_schema.tables WHERE table_schem
a = 'subdomain1 subdomain2') As bigint) ) As schema_size
  Rendered accounts/kapasitas.html.erb within layouts/admin (239.0ms)
Completed 200 OK in 2765ms (Views: 2208.1ms | ActiveRecord: 484.0ms)

on html.erb

  <tr>
    <td><%= account.subdomain %></td>
    <td><%= @schemasize %></td>
  </tr>

视图输出:http://i.cubeupload.com/jVrShN.png

不能为每个子域的大小架构。

我想要输出,例如:http://i.cubeupload.com/PMPBYn.png

我该怎么做? 任何想法?

1 个答案:

答案 0 :(得分:2)

首先,不要打扰pg_size_pretty,让显示代码担心格式化。

接下来,您需要了解select_rows返回一个数组数组(每行返回一个内部数组),并且数组条目将是字符串。

您的查询返回单行,因此您可以使用first提取该行,使用另一个first从该行中提取单个列。然后,您可以使用to_i来获取帮助者将理解的数字:

@schemasize = ActiveRecord::Base.connection.select_rows(%q{select CAST(...)})
                                           .first
                                           .first
                                           .to_i

并在显示时使用number_to_human_size

<%= number_to_human_size(@schemasize) %>

请参阅文档以获取number_to_human_size的可能选项列表。

如果您担心通过Fixnum来电溢出to_i,请不要。 to_i会根据需要切换为使用Bignum

1.9.2p312 :011 > '1'.to_i.class
 => Fixnum 
1.9.2p312 :012 > '12345678910111213141516'.to_i.class
 => Bignum 

number_to_human_sizeBignumFixnum一样快乐。

如果您始终希望结果以MB为单位,请使用to_f(或to_d代替BigDecimal)代替to_i,手动缩放(正如您所做的那样)现在),并使用String#%格式化它:

<%= '%.4f' % @schemasize %>

如果您想要每个架构的尺寸,那么您需要将table_schema = ...调整为table_schema in (...),然后调整GROUP BY table_schema。像这样:

select table_schema, sum(pg_total_relation_size(table_schema || '.' || table_name))
from information_schema.tables
where table_schema in ('subdomain1', 'subdomain2')
group by table_schema

这将从select_rows

为您提供这样的数组数组
[
  [ 'subdomain1', '3284762389' ],
  [ 'subdomain2', '129837' ]
]

然后你可以用:

将每行解包
@sizes = raw.map { |schema, size| [ schema, size.to_i ] }
# Or to_d as noted above

然后,您可以在ERB中循环@sizes并格式化上面的大小。