【问题标题】:Combine ActiveRecord::Result in .each loop在 .each 循环中组合 ActiveRecord::Result
【发布时间】:2016-03-03 21:54:54
【问题描述】:

我目前有这个工作,但必须有更好的方法。我有一个模型,可以在其中查询外部 oracle 数据库视图。在这种特殊情况下,我必须为每个 id 值运行一个查询并将这些结果组合到一个数组中。

这可行,但是需要对阵列进行大量维护才能以更易于使用的格式获取信息。希望有一种方法可以简化这一点:

def self.count_by_year(ids, year)
    start_date = DateTime.strptime(year.to_s, "%Y").strftime("%Y%m%d")
    end_date = DateTime.strptime(year.to_s, "%Y").end_of_year.strftime("%Y%m%d")
    bulk_issues = []
    if ids.size > 1
      ids.each do |uc|
        bulk_issues << (External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID='#{uc.id}' AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')")
      end
    else
      bulk_issues << (External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID='#{ids.first.id}' AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')")
    end
    return bulk_issues
  end

调用时返回以下内容:

[#<ActiveRecord::Result:0x007fdafd95ec20 @columns=["count(*)"], @rows=[[51]], @hash_rows=nil, @column_types={}>, #<ActiveRecord::Result:0x007fdafd95d320 @columns=["count(*)"], @rows=[[19]], @hash_rows=nil, @column_types={}>]

展平后返回:

[{"count(*)"=>51}, {"count(*)"=>19}]

提取数据很痛苦,因为我必须将值提取出来并将它们放入一个新数组中,以便将其格式化为我使用这些值的目的。

我要做的是让函数返回数组中的数据,如下所示:

[51, 19]

对此的任何帮助将不胜感激!

【问题讨论】:

  • 在进行原始查询时要格外小心,以免在查询中注入任何有害内容。使用占位符使这些更安全。

标签: ruby-on-rails arrays activerecord


【解决方案1】:

好吧,首先,Oracle supports IN expressions,所以不要使用您的 ids.each...,而是这样做:

bulk_issues = External.connection.select_all "SELECT COUNT(*) FROM DB WHERE ID IN (#{ids.map{|id| "'#{id.id}'"}.join(",")}) AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')"

那么这将不是一个数组,它只是一个像{"count(*)"=&gt;70} 这样的散列,所以要从那个调用中得到70

*, count = bulk_issues.first

所以在您的查询中添加一个AS,这样我们就可以确定我们的哈希将返回什么,您的整个方法就变成了:

def self.count_by_year(ids, year)
  start_date = DateTime.strptime(year.to_s, "%Y").strftime("%Y%m%d")
  end_date = DateTime.strptime(year.to_s, "%Y").end_of_year.strftime("%Y%m%d")

  res = External.connection.select_all("SELECT COUNT(*) AS count FROM DB WHERE ID IN (#{ids.map{|id| "'#{id.id}'"}.join(",")}) AND GROUP_NAME != 'CA' AND STATUS != 'Cancelled' AND (DATE_OPENED BETWEEN '#{start_date}' AND '#{end_date}')")

  return res.to_hash.first['count'].to_i
end

【讨论】:

  • 谢谢!我会尽快试一试并报告
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多